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

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: Add streaming-style comment in a branch of VisitExpression 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
« no previous file with comments | « no previous file | pkg/kernel/lib/transformations/closure/rewriter.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
karlklose 2017/06/19 11:58:14 Please check if this is still required.
Dmitry Stefantsov 2017/06/19 12:12:44 Thanks for pointing to this! Apparently, DillLibr
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 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 return super.visitForInStatement(node); 639 return super.visitForInStatement(node);
621 } 640 }
622 641
623 TreeNode visitThisExpression(ThisExpression node) { 642 TreeNode visitThisExpression(ThisExpression node) {
624 return isOuterMostContext 643 return isOuterMostContext
625 ? node 644 ? node
626 : context.lookup(thisAccess[currentMemberFunction]); 645 : context.lookup(thisAccess[currentMemberFunction]);
627 } 646 }
628 647
629 TreeNode visitStaticGet(StaticGet node) { 648 TreeNode visitStaticGet(StaticGet node) {
630 Member target = node.target; 649 // TODO(dmitryas): Add support for tear-offs. When added, uncomment this.
631 if (target is Procedure && target.kind == ProcedureKind.Method) { 650 //
632 VariableDeclaration contextVariable = new VariableDeclaration( 651 // Member target = node.target;
633 "#contextParameter", 652 // if (target is Procedure && target.kind == ProcedureKind.Method) {
634 type: const VectorType()); 653 // VariableDeclaration contextVariable = new VariableDeclaration(
635 Expression expression = getTearOffExpression( 654 // "#contextParameter",
636 null, node.target, contextVariable, new NullLiteral()); 655 // type: const VectorType());
637 expression.transformChildren(this); 656 // Expression expression = getTearOffExpression(
638 return expression; 657 // null, node.target, contextVariable, new NullLiteral());
639 } 658 // expression.transformChildren(this);
659 // return expression;
660 // }
640 return super.visitStaticGet(node); 661 return super.visitStaticGet(node);
641 } 662 }
642 663
643 TreeNode visitPropertyGet(PropertyGet node) { 664 TreeNode visitPropertyGet(PropertyGet node) {
644 Name tearOffName = tearOffGetterNames[node.name]; 665 Name tearOffName = tearOffGetterNames[node.name];
645 if (tearOffName != null) { 666 if (tearOffName != null) {
646 MethodInvocation replacement = new MethodInvocation( 667 PropertyGet replacement = new PropertyGet(node.receiver, tearOffName);
647 node.receiver, tearOffName, new Arguments(<Expression>[])); 668 return super.visitPropertyGet(replacement);
648 return super.visitMethodInvocation(replacement);
649 } 669 }
650 return super.visitPropertyGet(node); 670 return super.visitPropertyGet(node);
651 } 671 }
652 672
653 TreeNode visitCatch(Catch node) { 673 TreeNode visitCatch(Catch node) {
654 VariableDeclaration exception = node.exception; 674 VariableDeclaration exception = node.exception;
655 VariableDeclaration stackTrace = node.stackTrace; 675 VariableDeclaration stackTrace = node.stackTrace;
656 if (stackTrace != null && capturedVariables.contains(stackTrace)) { 676 if (stackTrace != null && capturedVariables.contains(stackTrace)) {
657 Block block = node.body = ensureBlock(node.body); 677 Block block = node.body = ensureBlock(node.body);
658 block.parent = node; 678 block.parent = node;
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
864 "#contextParameter", 884 "#contextParameter",
865 type: const VectorType()); 885 type: const VectorType());
866 Context parent = context; 886 Context parent = context;
867 context = context.toNestedContext( 887 context = context.toNestedContext(
868 new VariableAccessor(contextVariable, null, TreeNode.noOffset)); 888 new VariableAccessor(contextVariable, null, TreeNode.noOffset));
869 889
870 body.addStatement(new ReturnStatement(getTearOffExpression( 890 body.addStatement(new ReturnStatement(getTearOffExpression(
871 self, procedure, contextVariable, parent.expression))); 891 self, procedure, contextVariable, parent.expression)));
872 892
873 Procedure tearOffMethod = new Procedure( 893 Procedure tearOffMethod = new Procedure(
874 name, ProcedureKind.Method, tearOffMethodFunction, 894 name, ProcedureKind.Getter, tearOffMethodFunction,
875 fileUri: currentFileUri); 895 fileUri: currentFileUri);
876 newClassMembers.add(tearOffMethod); 896 newClassMembers.add(tearOffMethod);
877 897
878 resetContext(); 898 resetContext();
879 }); 899 });
880 } finally { 900 } finally {
881 currentMember = oldCurrentMember; 901 currentMember = oldCurrentMember;
882 currentMemberFunction = oldCurrentMemberFunction; 902 currentMemberFunction = oldCurrentMemberFunction;
883 } 903 }
884 } 904 }
885 } 905 }
OLDNEW
« no previous file with comments | « no previous file | pkg/kernel/lib/transformations/closure/rewriter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698