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

Side by Side Diff: pkg/kernel/lib/transformations/closure/converter.dart

Issue 2891053003: Add support for converted closures with explicit contexts to VM (Closed)
Patch Set: Disable closure conversion in frontend (was enabled for testing) Created 3 years, 6 months 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library kernel.transformations.closure.converter; 5 library kernel.transformations.closure.converter;
6 6
7 import '../../ast.dart' 7 import '../../ast.dart'
8 show 8 show
9 Arguments, 9 Arguments,
10 Block, 10 Block,
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 parent.body = initializerExpression; 223 parent.body = initializerExpression;
224 } else if (parent is FieldInitializer) { 224 } else if (parent is FieldInitializer) {
225 parent.value = initializerExpression; 225 parent.value = initializerExpression;
226 } else { 226 } else {
227 throw "Found unexpected node '${node.runtimeType}, expected a 'Let' " 227 throw "Found unexpected node '${node.runtimeType}, expected a 'Let' "
228 "or a 'FieldInitializer'."; 228 "or a 'FieldInitializer'.";
229 } 229 }
230 } 230 }
231 } 231 }
232 rewriter = null; 232 rewriter = null;
233 context = null;
233 // Transform constructor body. 234 // Transform constructor body.
234 FunctionNode function = node.function; 235 FunctionNode function = node.function;
235 if (function.body != null && function.body is! EmptyStatement) { 236 if (function.body != null && function.body is! EmptyStatement) {
236 setupContextForFunctionBody(function); 237 setupContextForFunctionBody(function);
237 VariableDeclaration self = thisAccess[currentMemberFunction]; 238 VariableDeclaration self = thisAccess[currentMemberFunction];
238 if (self != null) { 239 if (self != null) {
239 context.extend(self, new ThisExpression()); 240 context.extend(self, new ThisExpression());
240 } 241 }
241 node.function.accept(this); 242 node.function.accept(this);
242 resetContext(); 243 resetContext();
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 node.canonicalName?.unbind(); 418 node.canonicalName?.unbind();
418 addGetterForwarder(oldName, node); 419 addGetterForwarder(oldName, node);
419 } else if (node.kind == ProcedureKind.Method) { 420 } else if (node.kind == ProcedureKind.Method) {
420 addTearOffMethod(tearOffName, node); 421 addTearOffMethod(tearOffName, node);
421 } 422 }
422 } 423 }
423 } 424 }
424 425
425 FunctionNode function = node.function; 426 FunctionNode function = node.function;
426 if (function.body != null) { 427 if (function.body != null) {
428 bool hadSingleStatementBody = function.body is! Block;
429
427 setupContextForFunctionBody(function); 430 setupContextForFunctionBody(function);
428 VariableDeclaration self = thisAccess[currentMemberFunction]; 431 VariableDeclaration self = thisAccess[currentMemberFunction];
429 if (self != null) { 432 if (self != null) {
430 context.extend(self, new ThisExpression()); 433 context.extend(self, new ThisExpression());
431 } 434 }
432 node.transformChildren(this); 435 node.transformChildren(this);
433 resetContext(); 436 resetContext();
437
438 // Here a special case is handled: the body of the procedure was a single
439 // statement and after the transformation it is a block with a single
440 // statement inside. In this case we make this statement the body of the
441 // procedure again. It is required to follow the conventions imposed by
442 // [addClass] in [DillLibraryBuilder].
443 // See [dill_library_builder.dart]
444 // (../../../../front_end/lib/src/fasta/dill/dill_library_builder.dart)
445 // for details.
446 if (hadSingleStatementBody && function.body is Block) {
447 Block body = function.body;
448 if (body.statements.length == 1) {
449 function.body = body.statements[0];
450 function.body.parent = function;
451 }
452 }
434 } 453 }
435 454
436 return node; 455 return node;
437 } 456 }
438 457
439 void setupContextForFunctionBody(FunctionNode function) { 458 void setupContextForFunctionBody(FunctionNode function) {
440 Statement body = function.body; 459 Statement body = function.body;
441 assert(body != null); 460 assert(body != null);
442 currentMemberFunction = function; 461 currentMemberFunction = function;
443 // Ensure that the body is a block which becomes the current block. 462 // Ensure that the body is a block which becomes the current block.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 .forEach(extendContextWith); 495 .forEach(extendContextWith);
477 assert(node.body != null); 496 assert(node.body != null);
478 node.body = node.body.accept(this); 497 node.body = node.body.accept(this);
479 node.body.parent = node; 498 node.body.parent = node;
480 return node; 499 return node;
481 } 500 }
482 501
483 TreeNode visitBlock(Block node) { 502 TreeNode visitBlock(Block node) {
484 return saveContext(() { 503 return saveContext(() {
485 BlockRewriter blockRewriter = rewriter = rewriter.forNestedBlock(node); 504 BlockRewriter blockRewriter = rewriter = rewriter.forNestedBlock(node);
486 blockRewriter.transformStatements(node, this); 505 blockRewriter.transformStatements(this);
487 return node; 506 return node;
488 }); 507 });
489 } 508 }
490 509
491 TreeNode visitVariableDeclaration(VariableDeclaration node) { 510 TreeNode visitVariableDeclaration(VariableDeclaration node) {
492 node.transformChildren(this); 511 node.transformChildren(this);
493 512
494 if (!capturedVariables.contains(node)) return node; 513 if (!capturedVariables.contains(node)) return node;
495 if (node.initializer == null && node.parent is FunctionNode) { 514 if (node.initializer == null && node.parent is FunctionNode) {
496 // If the variable is a function parameter and doesn't have an 515 // If the variable is a function parameter and doesn't have an
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 null, node.target, contextVariable, new NullLiteral()); 655 null, node.target, contextVariable, new NullLiteral());
637 expression.transformChildren(this); 656 expression.transformChildren(this);
638 return expression; 657 return expression;
639 } 658 }
640 return super.visitStaticGet(node); 659 return super.visitStaticGet(node);
641 } 660 }
642 661
643 TreeNode visitPropertyGet(PropertyGet node) { 662 TreeNode visitPropertyGet(PropertyGet node) {
644 Name tearOffName = tearOffGetterNames[node.name]; 663 Name tearOffName = tearOffGetterNames[node.name];
645 if (tearOffName != null) { 664 if (tearOffName != null) {
646 MethodInvocation replacement = new MethodInvocation( 665 PropertyGet replacement = new PropertyGet(node.receiver, tearOffName);
647 node.receiver, tearOffName, new Arguments(<Expression>[])); 666 return super.visitPropertyGet(replacement);
648 return super.visitMethodInvocation(replacement);
649 } 667 }
650 return super.visitPropertyGet(node); 668 return super.visitPropertyGet(node);
651 } 669 }
652 670
653 TreeNode visitCatch(Catch node) { 671 TreeNode visitCatch(Catch node) {
654 VariableDeclaration exception = node.exception; 672 VariableDeclaration exception = node.exception;
655 VariableDeclaration stackTrace = node.stackTrace; 673 VariableDeclaration stackTrace = node.stackTrace;
656 if (stackTrace != null && capturedVariables.contains(stackTrace)) { 674 if (stackTrace != null && capturedVariables.contains(stackTrace)) {
657 Block block = node.body = ensureBlock(node.body); 675 Block block = node.body = ensureBlock(node.body);
658 block.parent = node; 676 block.parent = node;
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
864 "#contextParameter", 882 "#contextParameter",
865 type: const VectorType()); 883 type: const VectorType());
866 Context parent = context; 884 Context parent = context;
867 context = context.toNestedContext( 885 context = context.toNestedContext(
868 new VariableAccessor(contextVariable, null, TreeNode.noOffset)); 886 new VariableAccessor(contextVariable, null, TreeNode.noOffset));
869 887
870 body.addStatement(new ReturnStatement(getTearOffExpression( 888 body.addStatement(new ReturnStatement(getTearOffExpression(
871 self, procedure, contextVariable, parent.expression))); 889 self, procedure, contextVariable, parent.expression)));
872 890
873 Procedure tearOffMethod = new Procedure( 891 Procedure tearOffMethod = new Procedure(
874 name, ProcedureKind.Method, tearOffMethodFunction, 892 name, ProcedureKind.Getter, tearOffMethodFunction,
875 fileUri: currentFileUri); 893 fileUri: currentFileUri);
876 newClassMembers.add(tearOffMethod); 894 newClassMembers.add(tearOffMethod);
877 895
878 resetContext(); 896 resetContext();
879 }); 897 });
880 } finally { 898 } finally {
881 currentMember = oldCurrentMember; 899 currentMember = oldCurrentMember;
882 currentMemberFunction = oldCurrentMemberFunction; 900 currentMemberFunction = oldCurrentMemberFunction;
883 } 901 }
884 } 902 }
885 } 903 }
OLDNEW
« no previous file with comments | « no previous file | pkg/kernel/lib/transformations/closure/rewriter.dart » ('j') | runtime/vm/kernel_binary_flowgraph.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698