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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart

Issue 348053002: dart2dart: Support for all constants in new backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Formatting stuff Created 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 dart2js.ir_builder; 5 library dart2js.ir_builder;
6 6
7 import 'ir_nodes.dart' as ir; 7 import 'ir_nodes.dart' as ir;
8 import '../elements/elements.dart'; 8 import '../elements/elements.dart';
9 import '../dart2jslib.dart'; 9 import '../dart2jslib.dart';
10 import '../dart_types.dart'; 10 import '../dart_types.dart';
11 import '../source_file.dart'; 11 import '../source_file.dart';
12 import '../tree/tree.dart' as ast; 12 import '../tree/tree.dart' as ast;
13 import '../scanner/scannerlib.dart' show Token, isUserDefinableOperator; 13 import '../scanner/scannerlib.dart' show Token, isUserDefinableOperator;
14 import '../dart_backend/dart_backend.dart' show DartBackend; 14 import '../dart_backend/dart_backend.dart' show DartBackend;
15 import '../universe/universe.dart' show SelectorKind; 15 import '../universe/universe.dart' show SelectorKind;
16 import '../util/util.dart' show Link; 16 import '../util/util.dart' show Link;
17 import '../helpers/helpers.dart';
17 18
18 /** 19 /**
19 * This task iterates through all resolved elements and builds [ir.Node]s. The 20 * This task iterates through all resolved elements and builds [ir.Node]s. The
20 * nodes are stored in the [nodes] map and accessible through [hasIr] and 21 * nodes are stored in the [nodes] map and accessible through [hasIr] and
21 * [getIr]. 22 * [getIr].
22 * 23 *
23 * The functionality of the IrNodes is added gradually, therefore elements might 24 * The functionality of the IrNodes is added gradually, therefore elements might
24 * have an IR or not, depending on the language features that are used. For 25 * have an IR or not, depending on the language features that are used. For
25 * elements that do have an IR, the tree [ast.Node]s and the [Token]s are not 26 * elements that do have an IR, the tree [ast.Node]s and the [Token]s are not
26 * used in the rest of the compilation. This is ensured by setting the element's 27 * used in the rest of the compilation. This is ensured by setting the element's
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 if (signature.optionalParameterCount > 0) return false; 104 if (signature.optionalParameterCount > 0) return false;
104 105
105 // TODO(kmillikin): support getters and setters and static class members. 106 // TODO(kmillikin): support getters and setters and static class members.
106 // With the current Dart Tree emitter they just require recognizing them 107 // With the current Dart Tree emitter they just require recognizing them
107 // and generating the correct syntax. 108 // and generating the correct syntax.
108 if (element.isGetter || element.isSetter) return false; 109 if (element.isGetter || element.isSetter) return false;
109 110
110 // TODO(lry): support native functions (also in [visitReturn]). 111 // TODO(lry): support native functions (also in [visitReturn]).
111 if (function.isNative) return false; 112 if (function.isNative) return false;
112 113
114 // TODO(asgerf): support syntax for redirecting factory constructors
115 if (function is ConstructorElement && function.isRedirectingFactory) {
116 return false;
117 }
118
113 return true; 119 return true;
114 } 120 }
115 121
116 bool get inCheckedMode { 122 bool get inCheckedMode {
117 bool result = false; 123 bool result = false;
118 assert((result = true)); 124 assert((result = true));
119 return result; 125 return result;
120 } 126 }
121 127
122 SourceFile elementSourceFile(Element element) { 128 SourceFile elementSourceFile(Element element) {
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 entryArguments))); 615 entryArguments)));
610 current = resultContext; 616 current = resultContext;
611 } else { 617 } else {
612 add(resultContext); 618 add(resultContext);
613 } 619 }
614 return null; 620 return null;
615 } 621 }
616 622
617 ir.Primitive visitVariableDefinitions(ast.VariableDefinitions node) { 623 ir.Primitive visitVariableDefinitions(ast.VariableDefinitions node) {
618 assert(isOpen); 624 assert(isOpen);
625 if (node.modifiers.isConst) return giveup(node); // TODO(asgerf): const vars
619 for (ast.Node definition in node.definitions.nodes) { 626 for (ast.Node definition in node.definitions.nodes) {
620 Element element = elements[definition]; 627 Element element = elements[definition];
621 // Definitions are either SendSets if there is an initializer, or 628 // Definitions are either SendSets if there is an initializer, or
622 // Identifiers if there is no initializer. 629 // Identifiers if there is no initializer.
623 if (definition is ast.SendSet) { 630 if (definition is ast.SendSet) {
624 assert(!definition.arguments.isEmpty); 631 assert(!definition.arguments.isEmpty);
625 assert(definition.arguments.tail.isEmpty); 632 assert(definition.arguments.tail.isEmpty);
626 ir.Primitive initialValue = visit(definition.arguments.head); 633 ir.Primitive initialValue = visit(definition.arguments.head);
627 // In case a primitive was introduced for the initializer expression, 634 // In case a primitive was introduced for the initializer expression,
628 // use this variable element to help derive a good name for it. 635 // use this variable element to help derive a good name for it.
(...skipping 16 matching lines...) Expand all
645 return null; 652 return null;
646 } 653 }
647 654
648 // Build(Return(e), C) = C'[InvokeContinuation(return, x)] 655 // Build(Return(e), C) = C'[InvokeContinuation(return, x)]
649 // where (C', x) = Build(e, C) 656 // where (C', x) = Build(e, C)
650 // 657 //
651 // Return without a subexpression is translated as if it were return null. 658 // Return without a subexpression is translated as if it were return null.
652 ir.Primitive visitReturn(ast.Return node) { 659 ir.Primitive visitReturn(ast.Return node) {
653 assert(isOpen); 660 assert(isOpen);
654 // TODO(lry): support native returns. 661 // TODO(lry): support native returns.
655 if (node.beginToken.value == 'native') return giveup(); 662 if (node.beginToken.value == 'native') return giveup(node);
656 ir.Primitive value; 663 ir.Primitive value;
657 if (node.expression == null) { 664 if (node.expression == null) {
658 value = new ir.Constant(constantSystem.createNull()); 665 value = new ir.Constant(constantSystem.createNull());
659 add(new ir.LetPrim(value)); 666 add(new ir.LetPrim(value));
660 } else { 667 } else {
661 value = visit(node.expression); 668 value = visit(node.expression);
662 } 669 }
663 add(new ir.InvokeContinuation(returnContinuation, [value])); 670 add(new ir.InvokeContinuation(returnContinuation, [value]));
664 current = null; 671 current = null;
665 return null; 672 return null;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 } 769 }
763 770
764 Constant getConstantForNode(ast.Node node) { 771 Constant getConstantForNode(ast.Node node) {
765 Constant constant = 772 Constant constant =
766 compiler.backend.constants.getConstantForNode(node, elements); 773 compiler.backend.constants.getConstantForNode(node, elements);
767 assert(invariant(node, constant != null, 774 assert(invariant(node, constant != null,
768 message: 'No constant computed for $node')); 775 message: 'No constant computed for $node'));
769 return constant; 776 return constant;
770 } 777 }
771 778
772 bool isSupportedConst(Constant constant) {
773 return const SupportedConstantVisitor().visit(constant);
774 }
775
776 ir.Primitive visitLiteralList(ast.LiteralList node) { 779 ir.Primitive visitLiteralList(ast.LiteralList node) {
777 assert(isOpen); 780 assert(isOpen);
778 ir.Primitive result; 781 List<ir.Primitive> values = node.elements.nodes.mapToList(visit);
779 if (node.isConst) { 782 Constant constant = node.isConst ? getConstantForNode(node) : null;
780 // TODO(sigurdm): Remove when all constants are supported. 783 GenericType type = elements.getType(node);
781 Constant constant = getConstantForNode(node); 784 ir.Primitive result = new ir.LiteralList(type, values, constant);
782 if (!isSupportedConst(constant)) return giveup();
783 result = new ir.Constant(constant);
784 } else {
785 List<ir.Primitive> values = new List<ir.Primitive>();
786 node.elements.nodes.forEach((ast.Node node) {
787 values.add(visit(node));
788 });
789 result = new ir.LiteralList(values);
790 }
791 add(new ir.LetPrim(result)); 785 add(new ir.LetPrim(result));
792 return result; 786 return result;
793 } 787 }
794 788
795 ir.Primitive visitLiteralMap(ast.LiteralMap node) { 789 ir.Primitive visitLiteralMap(ast.LiteralMap node) {
796 assert(isOpen); 790 assert(isOpen);
797 ir.Primitive result; 791 List<ir.Primitive> keys = new List<ir.Primitive>();
798 if (node.isConst) { 792 List<ir.Primitive> values = new List<ir.Primitive>();
799 // TODO(sigurdm): Remove when all constants are supported. 793 node.entries.nodes.forEach((ast.LiteralMapEntry node) {
800 Constant constant = getConstantForNode(node); 794 keys.add(visit(node.key));
801 if (!isSupportedConst(constant)) return giveup(); 795 values.add(visit(node.value));
802 result = new ir.Constant(constant); 796 });
803 } else { 797 GenericType type = elements.getType(node);
804 List<ir.Primitive> keys = new List<ir.Primitive>(); 798 Constant constant = node.isConst ? getConstantForNode(node) : null;
805 List<ir.Primitive> values = new List<ir.Primitive>(); 799 ir.Primitive result = new ir.LiteralMap(type, keys, values, constant);
806 node.entries.nodes.forEach((ast.LiteralMapEntry node) {
807 keys.add(visit(node.key));
808 values.add(visit(node.value));
809 });
810 result = new ir.LiteralMap(keys, values);
811 }
812 add(new ir.LetPrim(result)); 800 add(new ir.LetPrim(result));
813 return result; 801 return result;
814 } 802 }
815 803
816 ir.Primitive visitLiteralSymbol(ast.LiteralSymbol node) { 804 ir.Primitive visitLiteralSymbol(ast.LiteralSymbol node) {
817 assert(isOpen); 805 assert(isOpen);
818 ir.Constant constant = new ir.Constant(getConstantForNode(node)); 806 ir.Constant constant = new ir.Constant(getConstantForNode(node));
819 add(new ir.LetPrim(constant)); 807 add(new ir.LetPrim(constant));
820 return constant; 808 return constant;
821 } 809 }
(...skipping 26 matching lines...) Expand all
848 836
849 ir.Primitive lookupLocal(Element element) { 837 ir.Primitive lookupLocal(Element element) {
850 int index = variableIndex[element]; 838 int index = variableIndex[element];
851 ir.Primitive value = assignedVars[index]; 839 ir.Primitive value = assignedVars[index];
852 return value == null ? freeVars[index] : value; 840 return value == null ? freeVars[index] : value;
853 } 841 }
854 842
855 // ==== Sends ==== 843 // ==== Sends ====
856 ir.Primitive visitAssert(ast.Send node) { 844 ir.Primitive visitAssert(ast.Send node) {
857 assert(isOpen); 845 assert(isOpen);
858 return giveup(); 846 return giveup(node);
859 } 847 }
860 848
861 ir.Primitive visitNamedArgument(ast.NamedArgument node) { 849 ir.Primitive visitNamedArgument(ast.NamedArgument node) {
862 assert(isOpen); 850 assert(isOpen);
863 return visit(node.expression); 851 return visit(node.expression);
864 } 852 }
865 853
866 ir.Primitive visitClosureSend(ast.Send node) { 854 ir.Primitive visitClosureSend(ast.Send node) {
867 assert(isOpen); 855 assert(isOpen);
868 Selector closureSelector = elements.getSelector(node); 856 Selector closureSelector = elements.getSelector(node);
(...skipping 19 matching lines...) Expand all
888 ir.Continuation k = new ir.Continuation([v]); 876 ir.Continuation k = new ir.Continuation([v]);
889 ir.Expression invoke = 877 ir.Expression invoke =
890 new ir.InvokeMethod(closureTarget, namedCallSelector, k, arguments); 878 new ir.InvokeMethod(closureTarget, namedCallSelector, k, arguments);
891 add(new ir.LetCont(k, invoke)); 879 add(new ir.LetCont(k, invoke));
892 return v; 880 return v;
893 } 881 }
894 882
895 ir.Primitive visitDynamicSend(ast.Send node) { 883 ir.Primitive visitDynamicSend(ast.Send node) {
896 assert(isOpen); 884 assert(isOpen);
897 if (node.receiver == null || node.receiver.isSuper()) { 885 if (node.receiver == null || node.receiver.isSuper()) {
898 return giveup(); 886 return giveup(node);
899 } 887 }
900 Selector selector = elements.getSelector(node); 888 Selector selector = elements.getSelector(node);
901 ir.Primitive receiver = visit(node.receiver); 889 ir.Primitive receiver = visit(node.receiver);
902 List<ir.Primitive> arguments = new List<ir.Primitive>(); 890 List<ir.Primitive> arguments = new List<ir.Primitive>();
903 for (ast.Node n in node.arguments) { 891 for (ast.Node n in node.arguments) {
904 arguments.add(visit(n)); 892 arguments.add(visit(n));
905 } 893 }
906 ir.Parameter v = new ir.Parameter(null); 894 ir.Parameter v = new ir.Parameter(null);
907 ir.Continuation k = new ir.Continuation([v]); 895 ir.Continuation k = new ir.Continuation([v]);
908 ir.Expression invoke = 896 ir.Expression invoke =
909 new ir.InvokeMethod(receiver, selector, k, arguments); 897 new ir.InvokeMethod(receiver, selector, k, arguments);
910 add(new ir.LetCont(k, invoke)); 898 add(new ir.LetCont(k, invoke));
911 return v; 899 return v;
912 } 900 }
913 901
914 ir.Primitive visitGetterSend(ast.Send node) { 902 ir.Primitive visitGetterSend(ast.Send node) {
915 assert(isOpen); 903 assert(isOpen);
916 Element element = elements[node]; 904 Element element = elements[node];
917 if (Elements.isLocal(element)) { 905 if (Elements.isLocal(element)) {
918 return lookupLocal(element); 906 return lookupLocal(element);
919 } else if (element == null || Elements.isInstanceField(element)) { 907 } else if (element == null || Elements.isInstanceField(element)) {
920 // TODO: Support implicit this. 908 // TODO: Support implicit this.
921 if (node.receiver == null) return giveup(); 909 if (node.receiver == null) return giveup(node);
922 910
923 ir.Primitive receiver = visit(node.receiver); 911 ir.Primitive receiver = visit(node.receiver);
924 ir.Parameter v = new ir.Parameter(null); 912 ir.Parameter v = new ir.Parameter(null);
925 ir.Continuation k = new ir.Continuation([v]); 913 ir.Continuation k = new ir.Continuation([v]);
926 Selector selector = elements.getSelector(node); 914 Selector selector = elements.getSelector(node);
927 assert(selector.kind == SelectorKind.GETTER); 915 assert(selector.kind == SelectorKind.GETTER);
928 ir.InvokeMethod invoke = new ir.InvokeMethod(receiver, selector, k, []); 916 ir.InvokeMethod invoke = new ir.InvokeMethod(receiver, selector, k, []);
929 add(new ir.LetCont(k, invoke)); 917 add(new ir.LetCont(k, invoke));
930 return v; 918 return v;
931 } else if (element.isField) { 919 } else if (element.isField) {
932 ir.Parameter v = new ir.Parameter(null); 920 ir.Parameter v = new ir.Parameter(null);
933 ir.Continuation k = new ir.Continuation([v]); 921 ir.Continuation k = new ir.Continuation([v]);
934 Selector selector = elements.getSelector(node); 922 Selector selector = elements.getSelector(node);
935 assert(selector.kind == SelectorKind.GETTER); 923 assert(selector.kind == SelectorKind.GETTER);
936 ir.InvokeStatic invoke = new ir.InvokeStatic(element, selector, k, []); 924 ir.InvokeStatic invoke = new ir.InvokeStatic(element, selector, k, []);
937 add(new ir.LetCont(k, invoke)); 925 add(new ir.LetCont(k, invoke));
938 return v; 926 return v;
927 } else if (Elements.isStaticOrTopLevelFunction(element)) {
928 ir.Primitive prim = new ir.Constant(new FunctionConstant(element));
929 add(new ir.LetPrim(prim));
930 return prim;
939 } else { 931 } else {
940 return giveup(); // TODO: figure out what's missing here 932 return giveup(node); // TODO(asgerf): figure out what's missing here
941 } 933 }
942 } 934 }
943 935
944 ir.Primitive translateLogicalOperator(ast.Operator op, 936 ir.Primitive translateLogicalOperator(ast.Operator op,
945 ast.Expression left, 937 ast.Expression left,
946 ast.Expression right) { 938 ast.Expression right) {
947 // e0 && e1 is translated as if e0 ? (e1 == true) : false. 939 // e0 && e1 is translated as if e0 ? (e1 == true) : false.
948 // e0 || e1 is translated as if e0 ? true : (e1 == true). 940 // e0 || e1 is translated as if e0 ? true : (e1 == true).
949 // The translation must convert both e0 and e1 to booleans and handle 941 // The translation must convert both e0 and e1 to booleans and handle
950 // local variable assignments in e1. 942 // local variable assignments in e1.
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 ast.Operator op = node.selector; 1027 ast.Operator op = node.selector;
1036 if (isUserDefinableOperator(op.source)) { 1028 if (isUserDefinableOperator(op.source)) {
1037 return visitDynamicSend(node); 1029 return visitDynamicSend(node);
1038 } 1030 }
1039 if (op.source == '&&' || op.source == '||') { 1031 if (op.source == '&&' || op.source == '||') {
1040 assert(node.receiver != null); 1032 assert(node.receiver != null);
1041 assert(!node.arguments.isEmpty); 1033 assert(!node.arguments.isEmpty);
1042 assert(node.arguments.tail.isEmpty); 1034 assert(node.arguments.tail.isEmpty);
1043 return translateLogicalOperator(op, node.receiver, node.arguments.head); 1035 return translateLogicalOperator(op, node.receiver, node.arguments.head);
1044 } 1036 }
1045 return giveup(); 1037 return giveup(node);
1046 } 1038 }
1047 1039
1048 // Build(StaticSend(f, arguments), C) = C[C'[InvokeStatic(f, xs)]] 1040 // Build(StaticSend(f, arguments), C) = C[C'[InvokeStatic(f, xs)]]
1049 // where (C', xs) = arguments.fold(Build, C) 1041 // where (C', xs) = arguments.fold(Build, C)
1050 ir.Primitive visitStaticSend(ast.Send node) { 1042 ir.Primitive visitStaticSend(ast.Send node) {
1051 assert(isOpen); 1043 assert(isOpen);
1052 Element element = elements[node]; 1044 Element element = elements[node];
1053 // TODO(lry): support constructors / factory calls. 1045 // TODO(lry): support constructors / factory calls.
1054 if (element.isConstructor) return giveup(); 1046 if (element.isConstructor) return giveup(node);
1055 // TODO(lry): support foreign functions. 1047 // TODO(lry): support foreign functions.
1056 if (element.isForeign(compiler)) return giveup(); 1048 if (element.isForeign(compiler)) return giveup(node);
1057 // TODO(lry): for elements that could not be resolved emit code to throw a 1049 // TODO(lry): for elements that could not be resolved emit code to throw a
1058 // [NoSuchMethodError]. 1050 // [NoSuchMethodError].
1059 if (element.isErroneous) return giveup(); 1051 if (element.isErroneous) return giveup(node);
1060 // TODO(lry): generate IR for object identicality. 1052 // TODO(lry): generate IR for object identicality.
1061 if (element == compiler.identicalFunction) giveup(); 1053 if (element == compiler.identicalFunction) giveup(node);
1062 1054
1063 Selector selector = elements.getSelector(node); 1055 Selector selector = elements.getSelector(node);
1064 1056
1065 // TODO(lry): support default arguments, need support for locals. 1057 // TODO(lry): support default arguments, need support for locals.
1066 List<ir.Definition> arguments = node.arguments.mapToList(visit, 1058 List<ir.Definition> arguments = node.arguments.mapToList(visit,
1067 growable:false); 1059 growable:false);
1068 ir.Parameter v = new ir.Parameter(null); 1060 ir.Parameter v = new ir.Parameter(null);
1069 ir.Continuation k = new ir.Continuation([v]); 1061 ir.Continuation k = new ir.Continuation([v]);
1070 ir.Expression invoke = 1062 ir.Expression invoke =
1071 new ir.InvokeStatic(element, selector, k, arguments); 1063 new ir.InvokeStatic(element, selector, k, arguments);
1072 add(new ir.LetCont(k, invoke)); 1064 add(new ir.LetCont(k, invoke));
1073 return v; 1065 return v;
1074 } 1066 }
1075 1067
1076 ir.Primitive visitSuperSend(ast.Send node) { 1068 ir.Primitive visitSuperSend(ast.Send node) {
1077 assert(isOpen); 1069 assert(isOpen);
1078 return giveup(); 1070 return giveup(node);
1079 } 1071 }
1080 1072
1081 ir.Primitive visitTypeReferenceSend(ast.Send node) { 1073 ir.Primitive visitTypeReferenceSend(ast.Send node) {
1082 assert(isOpen); 1074 assert(isOpen);
1083 return giveup(); 1075 if (node.argumentsNode != null) {
1076 // May happen in strange, invalid code.
1077 // TODO(asgerf): Generate code that throws a runtime error.
1078 return giveup(node);
1079 }
1080 Element element = elements[node];
1081 if (element is TypeDeclarationElement) {
1082 DartType typeType = compiler.backend.typeImplementation.rawType;
1083 ir.Primitive prim =
1084 new ir.Constant(new TypeConstant(element.rawType, typeType));
1085 add(new ir.LetPrim(prim));
1086 return prim;
1087 } else if (element.isTypeVariable) {
1088 // TODO(asgerf): Introduce IR to reify type variables
1089 return giveup(node);
1090 } else {
1091 // TODO(asgerf): Any other cases?
1092 return giveup(node);
1093 }
1084 } 1094 }
1085 1095
1086 ir.Primitive visitSendSet(ast.SendSet node) { 1096 ir.Primitive visitSendSet(ast.SendSet node) {
1087 assert(isOpen); 1097 assert(isOpen);
1088 Element element = elements[node]; 1098 Element element = elements[node];
1089 ast.Operator op = node.assignmentOperator; 1099 ast.Operator op = node.assignmentOperator;
1090 ir.Primitive result; 1100 ir.Primitive result;
1091 ir.Primitive getter; 1101 ir.Primitive getter;
1092 if (op.source == '=') { 1102 if (op.source == '=') {
1093 if (Elements.isLocal(element)) { 1103 if (Elements.isLocal(element)) {
(...skipping 12 matching lines...) Expand all
1106 Selector selector = elements.getSelector(node); 1116 Selector selector = elements.getSelector(node);
1107 ir.Definition arg = visit(node.arguments.head); 1117 ir.Definition arg = visit(node.arguments.head);
1108 ir.InvokeStatic invoke = 1118 ir.InvokeStatic invoke =
1109 new ir.InvokeStatic(element, selector, k, [arg]); 1119 new ir.InvokeStatic(element, selector, k, [arg]);
1110 add(new ir.LetCont(k, invoke)); 1120 add(new ir.LetCont(k, invoke));
1111 return arg; 1121 return arg;
1112 } else if (node.receiver == null) { 1122 } else if (node.receiver == null) {
1113 // Nodes that fall in this case: 1123 // Nodes that fall in this case:
1114 // - Unresolved top-level 1124 // - Unresolved top-level
1115 // - Assignment to final variable (will not be resolved) 1125 // - Assignment to final variable (will not be resolved)
1116 return giveup(); 1126 return giveup(node);
1117 } else { 1127 } else {
1118 // Setter or index-setter invocation 1128 // Setter or index-setter invocation
1119 assert(node.receiver != null); 1129 assert(node.receiver != null);
1120 if (node.receiver.isSuper()) return giveup(); 1130 if (node.receiver.isSuper()) return giveup(node);
1121 1131
1122 ir.Primitive receiver = visit(node.receiver); 1132 ir.Primitive receiver = visit(node.receiver);
1123 ir.Parameter v = new ir.Parameter(null); 1133 ir.Parameter v = new ir.Parameter(null);
1124 ir.Continuation k = new ir.Continuation([v]); 1134 ir.Continuation k = new ir.Continuation([v]);
1125 Selector selector = elements.getSelector(node); 1135 Selector selector = elements.getSelector(node);
1126 assert(selector.kind == SelectorKind.SETTER || 1136 assert(selector.kind == SelectorKind.SETTER ||
1127 selector.kind == SelectorKind.INDEX); 1137 selector.kind == SelectorKind.INDEX);
1128 List<ir.Definition> args = node.arguments.mapToList(visit, 1138 List<ir.Definition> args = node.arguments.mapToList(visit,
1129 growable:false); 1139 growable:false);
1130 ir.InvokeMethod invoke = 1140 ir.InvokeMethod invoke =
1131 new ir.InvokeMethod(receiver, selector, k, args); 1141 new ir.InvokeMethod(receiver, selector, k, args);
1132 add(new ir.LetCont(k, invoke)); 1142 add(new ir.LetCont(k, invoke));
1133 return args.last; 1143 return args.last;
1134 } 1144 }
1135 } else if (ast.Operator.COMPLEX_OPERATORS.contains(op.source)) { 1145 } else if (ast.Operator.COMPLEX_OPERATORS.contains(op.source)) {
1136 Element selectorElement = elements[node.selector]; 1146 Element selectorElement = elements[node.selector];
1137 if (selectorElement != null && !selectorElement.isAssignable) { 1147 if (selectorElement != null && !selectorElement.isAssignable) {
1138 return giveup(); 1148 return giveup(node);
1139 } 1149 }
1140 if (!Elements.isLocal(selectorElement)) return giveup(); 1150 if (!Elements.isLocal(selectorElement)) return giveup(node);
1141 1151
1142 Selector selector = elements.getOperatorSelectorInComplexSendSet(node); 1152 Selector selector = elements.getOperatorSelectorInComplexSendSet(node);
1143 getter = lookupLocal(selectorElement); 1153 getter = lookupLocal(selectorElement);
1144 1154
1145 ir.Primitive arg; 1155 ir.Primitive arg;
1146 if (ast.Operator.INCREMENT_OPERATORS.contains(op.source)) { 1156 if (ast.Operator.INCREMENT_OPERATORS.contains(op.source)) {
1147 assert(node.arguments.isEmpty); 1157 assert(node.arguments.isEmpty);
1148 arg = new ir.Constant(constantSystem.createInt(1)); 1158 arg = new ir.Constant(constantSystem.createInt(1));
1149 add(new ir.LetPrim(arg)); 1159 add(new ir.LetPrim(arg));
1150 } else { 1160 } else {
(...skipping 19 matching lines...) Expand all
1170 } else { 1180 } else {
1171 compiler.internalError(node, "Unknown assignment operator ${op.source}"); 1181 compiler.internalError(node, "Unknown assignment operator ${op.source}");
1172 return null; 1182 return null;
1173 } 1183 }
1174 } 1184 }
1175 1185
1176 ir.Primitive visitNewExpression(ast.NewExpression node) { 1186 ir.Primitive visitNewExpression(ast.NewExpression node) {
1177 assert(isOpen); 1187 assert(isOpen);
1178 FunctionElement element = elements[node.send]; 1188 FunctionElement element = elements[node.send];
1179 if (Elements.isUnresolved(element)) { 1189 if (Elements.isUnresolved(element)) {
1180 return giveup(); 1190 return giveup(node);
1181 } 1191 }
1182 Selector selector = elements.getSelector(node.send); 1192 Selector selector = elements.getSelector(node.send);
1183 ast.Node selectorNode = node.send.selector; 1193 ast.Node selectorNode = node.send.selector;
1184 GenericType type = elements.getType(node); 1194 GenericType type = elements.getType(node);
1185 List<ir.Definition> args = node.send.arguments.mapToList(visit, 1195 List<ir.Primitive> args =
1186 growable:false); 1196 node.send.arguments.mapToList(visit, growable:false);
1187 if (node.isConst) { 1197 if (node.isConst) {
1188 List<ir.Primitive> arguments = new List<ir.Primitive>(); 1198 ir.Primitive result = new ir.InvokeConstConstructor(type, element,
1189 node.send.arguments.forEach((ast.Node node) { 1199 selector, args, getConstantForNode(node));
1190 arguments.add(visit(node));
1191 });
1192 ir.Primitive result = new ir.InvokeConstConstructor(type, element, selecto r,
1193 arguments);
1194 add(new ir.LetPrim(result)); 1200 add(new ir.LetPrim(result));
1195 return result; 1201 return result;
1196 } 1202 }
1197 ir.Parameter v = new ir.Parameter(null); 1203 ir.Parameter v = new ir.Parameter(null);
1198 ir.Continuation k = new ir.Continuation([v]); 1204 ir.Continuation k = new ir.Continuation([v]);
1199 ir.InvokeConstructor invoke = new ir.InvokeConstructor( 1205 ir.InvokeConstructor invoke =
1200 type, 1206 new ir.InvokeConstructor(type, element,selector, k, args);
1201 element,
1202 selector,
1203 k,
1204 args);
1205 add(new ir.LetCont(k, invoke)); 1207 add(new ir.LetCont(k, invoke));
1206 return v; 1208 return v;
1207 } 1209 }
1208 1210
1209 ir.Primitive visitStringJuxtaposition(ast.StringJuxtaposition node) { 1211 ir.Primitive visitStringJuxtaposition(ast.StringJuxtaposition node) {
1210 ir.Primitive first = visit(node.first); 1212 ir.Primitive first = visit(node.first);
1211 ir.Primitive second = visit(node.second); 1213 ir.Primitive second = visit(node.second);
1212 ir.Parameter v = new ir.Parameter(null); 1214 ir.Parameter v = new ir.Parameter(null);
1213 ir.Continuation k = new ir.Continuation([v]); 1215 ir.Continuation k = new ir.Continuation([v]);
1214 ir.ConcatenateStrings concat = 1216 ir.ConcatenateStrings concat =
(...skipping 13 matching lines...) Expand all
1228 } 1230 }
1229 ir.Parameter v = new ir.Parameter(null); 1231 ir.Parameter v = new ir.Parameter(null);
1230 ir.Continuation k = new ir.Continuation([v]); 1232 ir.Continuation k = new ir.Continuation([v]);
1231 ir.ConcatenateStrings concat = new ir.ConcatenateStrings(k, arguments); 1233 ir.ConcatenateStrings concat = new ir.ConcatenateStrings(k, arguments);
1232 add(new ir.LetCont(k, concat)); 1234 add(new ir.LetCont(k, concat));
1233 return v; 1235 return v;
1234 } 1236 }
1235 1237
1236 static final String ABORT_IRNODE_BUILDER = "IrNode builder aborted"; 1238 static final String ABORT_IRNODE_BUILDER = "IrNode builder aborted";
1237 1239
1238 ir.Primitive giveup() => throw ABORT_IRNODE_BUILDER; 1240 ir.Primitive giveup(ast.Node node) {
1241 throw ABORT_IRNODE_BUILDER;
1242 }
asgerf 2014/06/20 15:02:10 I find myself adding and removing the node paramet
sigurdm 2014/06/23 07:22:20 Yes! And maybe we can even add an optional "reason
Kevin Millikin (Google) 2014/06/23 08:03:06 Yes, please.
1239 1243
1240 ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) { 1244 ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) {
1241 try { 1245 try {
1242 return action(); 1246 return action();
1243 } catch(e) { 1247 } catch(e) {
1244 if (e == ABORT_IRNODE_BUILDER) return null; 1248 if (e == ABORT_IRNODE_BUILDER) return null;
1245 rethrow; 1249 rethrow;
1246 } 1250 }
1247 } 1251 }
1248 1252
1249 void internalError(String reason, {ast.Node node}) { 1253 void internalError(String reason, {ast.Node node}) {
1250 giveup(); 1254 giveup(node);
1251 } 1255 }
1252 } 1256 }
1253 1257
1254 // While we don't support all constants we need to filter out the unsupported
1255 // ones:
1256 class SupportedConstantVisitor extends ConstantVisitor<bool> {
1257 const SupportedConstantVisitor();
1258
1259 bool visit(Constant constant) => constant.accept(this);
1260 bool visitFunction(FunctionConstant constant) => false;
1261 bool visitNull(NullConstant constant) => true;
1262 bool visitInt(IntConstant constant) => true;
1263 bool visitDouble(DoubleConstant constant) => true;
1264 bool visitTrue(TrueConstant constant) => true;
1265 bool visitFalse(FalseConstant constant) => true;
1266 bool visitString(StringConstant constant) => true;
1267 bool visitList(ListConstant constant) {
1268 return constant.entries.every(visit);
1269 }
1270 bool visitMap(MapConstant constant) {
1271 return visit(constant.keys) && constant.values.every(visit);
1272 }
1273 bool visitConstructed(ConstructedConstant constant) => false;
1274 bool visitType(TypeConstant constant) => false;
1275 bool visitInterceptor(InterceptorConstant constant) => false;
1276 bool visitDummy(DummyConstant constant) => false;
1277 bool visitDeferred(DeferredConstant constant) => false;
1278 }
1279
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698