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

Side by Side Diff: pkg/compiler/lib/src/js_backend/codegen/codegen.dart

Issue 1562893002: dart2js cps: Generate increment and compound operators. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Also compound string concatenation Created 4 years, 11 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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 code_generator; 5 library code_generator;
6 6
7 import 'glue.dart'; 7 import 'glue.dart';
8 8
9 import '../../closure.dart' show 9 import '../../closure.dart' show
10 ClosureClassElement; 10 ClosureClassElement;
11 import '../../common.dart'; 11 import '../../common.dart';
12 import '../../common/codegen.dart' show 12 import '../../common/codegen.dart' show
13 CodegenRegistry; 13 CodegenRegistry;
14 import '../../constants/values.dart'; 14 import '../../constants/values.dart';
15 import '../../dart_types.dart'; 15 import '../../dart_types.dart';
16 import '../../elements/elements.dart'; 16 import '../../elements/elements.dart';
17 import '../../io/source_information.dart' show 17 import '../../io/source_information.dart' show
18 SourceInformation; 18 SourceInformation;
19 import '../../js/js.dart' as js; 19 import '../../js/js.dart' as js;
20 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir; 20 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir;
21 import '../../tree_ir/tree_ir_nodes.dart' show 21 import '../../tree_ir/tree_ir_nodes.dart' show
22 BuiltinMethod, 22 BuiltinMethod,
23 BuiltinOperator; 23 BuiltinOperator,
24 isCompoundableOperator;
24 import '../../types/types.dart' show 25 import '../../types/types.dart' show
25 TypeMask; 26 TypeMask;
26 import '../../universe/call_structure.dart' show 27 import '../../universe/call_structure.dart' show
27 CallStructure; 28 CallStructure;
28 import '../../universe/selector.dart' show 29 import '../../universe/selector.dart' show
29 Selector; 30 Selector;
30 import '../../universe/use.dart' show 31 import '../../universe/use.dart' show
31 DynamicUse, 32 DynamicUse,
32 StaticUse, 33 StaticUse,
33 TypeUse; 34 TypeUse;
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 499
499 @override 500 @override
500 js.Expression visitVariableUse(tree_ir.VariableUse node) { 501 js.Expression visitVariableUse(tree_ir.VariableUse node) {
501 return buildVariableAccess(node.variable); 502 return buildVariableAccess(node.variable);
502 } 503 }
503 504
504 js.Expression buildVariableAccess(tree_ir.Variable variable) { 505 js.Expression buildVariableAccess(tree_ir.Variable variable) {
505 return new js.VariableUse(getVariableName(variable)); 506 return new js.VariableUse(getVariableName(variable));
506 } 507 }
507 508
509 /// Returns the JS operator for the given built-in operator for use in a
510 /// compound assignment (not including the '=' sign).
511 String getAsCompoundOperator(BuiltinOperator operator) {
512 switch (operator) {
513 case BuiltinOperator.NumAdd:
514 case BuiltinOperator.StringConcatenate:
515 return '+';
516 case BuiltinOperator.NumSubtract:
517 return '-';
518 case BuiltinOperator.NumMultiply:
519 return '*';
520 case BuiltinOperator.NumDivide:
521 return '/';
522 case BuiltinOperator.NumRemainder:
523 return '%';
524 default:
525 throw 'Not a compoundable operator: $operator';
526 }
527 }
528
529 bool isCompoundableBuiltin(tree_ir.Expression exp) {
530 return exp is tree_ir.ApplyBuiltinOperator &&
531 exp.arguments.length == 2 &&
532 isCompoundableOperator(exp.operator);
533 }
534
535 bool isOneConstant(tree_ir.Expression exp) {
536 return exp is tree_ir.Constant && exp.value.isOne;
537 }
538
539 js.Expression makeAssignment(
540 js.Expression leftHand,
541 tree_ir.Expression value,
542 {BuiltinOperator compound}) {
543 if (isOneConstant(value)) {
544 if (compound == BuiltinOperator.NumAdd) {
545 return new js.Prefix('++', leftHand);
546 }
547 if (compound == BuiltinOperator.NumSubtract) {
548 return new js.Prefix('--', leftHand);
549 }
550 }
551 if (compound != null) {
552 return new js.Assignment.compound(leftHand,
553 getAsCompoundOperator(compound), visitExpression(value));
554 }
555 return new js.Assignment(leftHand, visitExpression(value));
556 }
557
508 @override 558 @override
509 js.Expression visitAssign(tree_ir.Assign node) { 559 js.Expression visitAssign(tree_ir.Assign node) {
510 return new js.Assignment( 560 js.Expression variable = buildVariableAccess(node.variable);
511 buildVariableAccess(node.variable), 561 if (isCompoundableBuiltin(node.value)) {
512 visitExpression(node.value)); 562 tree_ir.ApplyBuiltinOperator rhs = node.value;
563 tree_ir.Expression left = rhs.arguments[0];
564 tree_ir.Expression right = rhs.arguments[1];
565 if (left is tree_ir.VariableUse && left.variable == node.variable) {
566 return makeAssignment(variable, right, compound: rhs.operator);
567 }
568 }
569 return makeAssignment(variable, node.value);
513 } 570 }
514 571
515 @override 572 @override
516 void visitContinue(tree_ir.Continue node) { 573 void visitContinue(tree_ir.Continue node) {
517 tree_ir.Statement next = fallthrough.target; 574 tree_ir.Statement next = fallthrough.target;
518 if (node.target.binding == next || 575 if (node.target.binding == next ||
519 next is tree_ir.Continue && node.target == next.target) { 576 next is tree_ir.Continue && node.target == next.target) {
520 // Fall through to continue target or to equivalent continue. 577 // Fall through to continue target or to equivalent continue.
521 fallthrough.use(); 578 fallthrough.use();
522 } else if (node.target.binding == shortContinue.target) { 579 } else if (node.target.binding == shortContinue.target) {
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 873
817 @override 874 @override
818 js.Expression visitGetField(tree_ir.GetField node) { 875 js.Expression visitGetField(tree_ir.GetField node) {
819 registry.registerStaticUse(new StaticUse.fieldGet(node.field)); 876 registry.registerStaticUse(new StaticUse.fieldGet(node.field));
820 return new js.PropertyAccess( 877 return new js.PropertyAccess(
821 visitExpression(node.object), 878 visitExpression(node.object),
822 glue.instanceFieldPropertyName(node.field)); 879 glue.instanceFieldPropertyName(node.field));
823 } 880 }
824 881
825 @override 882 @override
826 js.Assignment visitSetField(tree_ir.SetField node) { 883 js.Expression visitSetField(tree_ir.SetField node) {
827 registry.registerStaticUse(new StaticUse.fieldSet(node.field)); 884 registry.registerStaticUse(new StaticUse.fieldSet(node.field));
828 js.PropertyAccess field = 885 js.PropertyAccess field =
829 new js.PropertyAccess( 886 new js.PropertyAccess(
830 visitExpression(node.object), 887 visitExpression(node.object),
831 glue.instanceFieldPropertyName(node.field)); 888 glue.instanceFieldPropertyName(node.field));
832 return new js.Assignment(field, visitExpression(node.value)); 889 return makeAssignment(field, node.value, compound: node.compound);
833 } 890 }
834 891
835 @override 892 @override
836 js.Expression visitGetStatic(tree_ir.GetStatic node) { 893 js.Expression visitGetStatic(tree_ir.GetStatic node) {
837 assert(node.element is FieldElement || node.element is FunctionElement); 894 assert(node.element is FieldElement || node.element is FunctionElement);
838 if (node.element is FunctionElement) { 895 if (node.element is FunctionElement) {
839 // Tear off a method. 896 // Tear off a method.
840 registry.registerStaticUse( 897 registry.registerStaticUse(
841 new StaticUse.staticTearOff(node.element.declaration)); 898 new StaticUse.staticTearOff(node.element.declaration));
842 return glue.isolateStaticClosureAccess(node.element); 899 return glue.isolateStaticClosureAccess(node.element);
(...skipping 29 matching lines...) Expand all
872 929
873 @override 930 @override
874 js.Expression visitGetIndex(tree_ir.GetIndex node) { 931 js.Expression visitGetIndex(tree_ir.GetIndex node) {
875 return new js.PropertyAccess( 932 return new js.PropertyAccess(
876 visitExpression(node.object), 933 visitExpression(node.object),
877 visitExpression(node.index)); 934 visitExpression(node.index));
878 } 935 }
879 936
880 @override 937 @override
881 js.Expression visitSetIndex(tree_ir.SetIndex node) { 938 js.Expression visitSetIndex(tree_ir.SetIndex node) {
882 return js.js('#[#] = #', 939 js.Expression index = new js.PropertyAccess(
883 [visitExpression(node.object), 940 visitExpression(node.object), visitExpression(node.index));
884 visitExpression(node.index), 941 return makeAssignment(index, node.value, compound: node.compound);
885 visitExpression(node.value)]);
886 } 942 }
887 943
888 js.Expression buildStaticHelperInvocation( 944 js.Expression buildStaticHelperInvocation(
889 FunctionElement helper, 945 FunctionElement helper,
890 List<js.Expression> arguments, 946 List<js.Expression> arguments,
891 {SourceInformation sourceInformation}) { 947 {SourceInformation sourceInformation}) {
892 registry.registerStaticUse(new StaticUse.staticInvoke( 948 registry.registerStaticUse(new StaticUse.staticInvoke(
893 helper, new CallStructure.unnamed(arguments.length))); 949 helper, new CallStructure.unnamed(arguments.length)));
894 return buildStaticInvoke( 950 return buildStaticInvoke(
895 helper, arguments, sourceInformation: sourceInformation); 951 helper, arguments, sourceInformation: sourceInformation);
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 void registerDefaultParameterValues(ExecutableElement element) { 1214 void registerDefaultParameterValues(ExecutableElement element) {
1159 if (element is! FunctionElement) return; 1215 if (element is! FunctionElement) return;
1160 FunctionElement function = element; 1216 FunctionElement function = element;
1161 if (function.isStatic) return; // Defaults are inlined at call sites. 1217 if (function.isStatic) return; // Defaults are inlined at call sites.
1162 function.functionSignature.forEachOptionalParameter((param) { 1218 function.functionSignature.forEachOptionalParameter((param) {
1163 ConstantValue constant = glue.getDefaultParameterValue(param); 1219 ConstantValue constant = glue.getDefaultParameterValue(param);
1164 registry.registerCompileTimeConstant(constant); 1220 registry.registerCompileTimeConstant(constant);
1165 }); 1221 });
1166 } 1222 }
1167 } 1223 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/builtin_operator.dart ('k') | pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698