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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_backend/namer.dart

Issue 12334070: Support runtime check of function types. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Minor fix Created 7 years, 5 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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 part of js_backend; 5 part of js_backend;
6 6
7 /** 7 /**
8 * Assigns JavaScript identifiers to Dart variables, class-names and members. 8 * Assigns JavaScript identifiers to Dart variables, class-names and members.
9 */ 9 */
10 class Namer implements ClosureNamer { 10 class Namer implements ClosureNamer {
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 if (_jsVariableReserved == null) { 166 if (_jsVariableReserved == null) {
167 _jsVariableReserved = new Set<String>(); 167 _jsVariableReserved = new Set<String>();
168 _jsVariableReserved.addAll(javaScriptKeywords); 168 _jsVariableReserved.addAll(javaScriptKeywords);
169 _jsVariableReserved.addAll(reservedPropertySymbols); 169 _jsVariableReserved.addAll(reservedPropertySymbols);
170 _jsVariableReserved.addAll(reservedGlobalSymbols); 170 _jsVariableReserved.addAll(reservedGlobalSymbols);
171 } 171 }
172 return _jsVariableReserved; 172 return _jsVariableReserved;
173 } 173 }
174 174
175 final String CURRENT_ISOLATE; 175 final String CURRENT_ISOLATE;
176 String get GLOBAL_OBJECT => CURRENT_ISOLATE;
176 177
177 final String getterPrefix = r'get$'; 178 final String getterPrefix = r'get$';
178 final String setterPrefix = r'set$'; 179 final String setterPrefix = r'set$';
179 final String metadataField = '@'; 180 final String metadataField = '@';
180 181
181 /** 182 /**
182 * Map from top-level or static elements to their unique identifiers provided 183 * Map from top-level or static elements to their unique identifiers provided
183 * by [getName]. 184 * by [getName].
184 * 185 *
185 * Invariant: Keys must be declaration elements. 186 * Invariant: Keys must be declaration elements.
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 } 760 }
760 761
761 String isolateStaticClosureAccess(Element element) { 762 String isolateStaticClosureAccess(Element element) {
762 return "$CURRENT_ISOLATE.${getStaticClosureName(element)}"; 763 return "$CURRENT_ISOLATE.${getStaticClosureName(element)}";
763 } 764 }
764 765
765 String operatorIsPrefix() => r'$is'; 766 String operatorIsPrefix() => r'$is';
766 767
767 String operatorAsPrefix() => r'$as'; 768 String operatorAsPrefix() => r'$as';
768 769
770 String operatorSignature() => r'$signature';
771
772 String functionTypeTag() => r'func';
773
774 String functionTypeVoidReturnTag() => r'void';
775
776 String functionTypeReturnTypeTag() => r'ret';
777
778 String functionTypeRequiredParametersTag() => r'args';
779
780 String functionTypeOptionalParametersTag() => r'opt';
781
782 String functionTypeNamedParametersTag() => r'named';
783
784 Map<FunctionType,String> functionTypeNameMap =
785 new Map<FunctionType,String>();
786 FunctionTypeNamer functionTypeNamer = new FunctionTypeNamer();
787
788 String getFunctionTypeName(FunctionType functionType) {
789 return functionTypeNameMap.putIfAbsent(functionType, () {
790 String proposedName = functionTypeNamer.computeName(functionType);
791 String freshName = getFreshName(proposedName, usedInstanceNames,
792 suggestedInstanceNames, ensureSafe: true);
793 return freshName;
794 });
795 }
796
797 String operatorIsType(DartType type) {
798 if (type.kind == TypeKind.FUNCTION) {
799 // TODO(erikcorry): Reduce from $isx to ix when we are minifying.
800 return '${operatorIsPrefix()}_${getFunctionTypeName(type)}';
801 }
802 return operatorIs(type.element);
803 }
804
769 String operatorIs(Element element) { 805 String operatorIs(Element element) {
770 // TODO(erikcorry): Reduce from $isx to ix when we are minifying. 806 // TODO(erikcorry): Reduce from $isx to ix when we are minifying.
771 return '${operatorIsPrefix()}${getRuntimeTypeName(element)}'; 807 return '${operatorIsPrefix()}${getRuntimeTypeName(element)}';
772 } 808 }
773 809
774 /* 810 /*
775 * Returns a name that does not clash with reserved JS keywords, 811 * Returns a name that does not clash with reserved JS keywords,
776 * and also ensures it won't clash with other identifiers. 812 * and also ensures it won't clash with other identifiers.
777 */ 813 */
778 String _safeName(String name, Set<String> reserved) { 814 String _safeName(String name, Set<String> reserved) {
779 if (reserved.contains(name) || name.startsWith(r'$')) { 815 if (reserved.contains(name) || name.startsWith(r'$')) {
780 name = '\$$name'; 816 name = '\$$name';
781 } 817 }
782 assert(!reserved.contains(name)); 818 assert(!reserved.contains(name));
783 return name; 819 return name;
784 } 820 }
785 821
786 String substitutionName(Element element) { 822 String substitutionName(Element element) {
787 return '${operatorAsPrefix()}${getName(element)}'; 823 return '${operatorAsPrefix()}${getName(element)}';
788 } 824 }
789 825
826 String signatureLocation(FunctionType type) {
827 ClassElement classElement = Types.getClassContext(type);
828 if (classElement != null) {
829 return '${isolateAccess(classElement)}';
830 } else {
831 return '${GLOBAL_OBJECT}';
832 }
833 }
834
835 String signatureName(FunctionType type) {
836 String signature = '${operatorSignature()}_${getFunctionTypeName(type)}';
837 return '${signatureLocation(type)}.$signature';
838 }
839
790 String safeName(String name) => _safeName(name, jsReserved); 840 String safeName(String name) => _safeName(name, jsReserved);
791 String safeVariableName(String name) => _safeName(name, jsVariableReserved); 841 String safeVariableName(String name) => _safeName(name, jsVariableReserved);
792 842
793 SourceString operatorNameToIdentifier(SourceString name) { 843 SourceString operatorNameToIdentifier(SourceString name) {
794 if (name == null) return null; 844 if (name == null) return null;
795 String value = name.stringValue; 845 String value = name.stringValue;
796 if (value == null) { 846 if (value == null) {
797 return name; 847 return name;
798 } else if (value == '==') { 848 } else if (value == '==') {
799 return const SourceString(r'$eq'); 849 return const SourceString(r'$eq');
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 } else if (value == '-') { 884 } else if (value == '-') {
835 return const SourceString(r'$sub'); 885 return const SourceString(r'$sub');
836 } else if (value == 'unary-') { 886 } else if (value == 'unary-') {
837 return const SourceString(r'$negate'); 887 return const SourceString(r'$negate');
838 } else { 888 } else {
839 return name; 889 return name;
840 } 890 }
841 } 891 }
842 } 892 }
843 893
844
845 /** 894 /**
846 * Generator of names for [Constant] values. 895 * Generator of names for [Constant] values.
847 * 896 *
848 * The names are stable under perturbations of the source. The name is either a 897 * The names are stable under perturbations of the source. The name is either a
849 * short sequence of words, if this can be found from the constant, or a type 898 * short sequence of words, if this can be found from the constant, or a type
850 * followed by a hash tag. 899 * followed by a hash tag.
851 * 900 *
852 * List_imX // A List, with hash tag. 901 * List_imX // A List, with hash tag.
853 * C_Sentinel // const Sentinel(), "C_" added to avoid clash 902 * C_Sentinel // const Sentinel(), "C_" added to avoid clash
854 * // with class name. 903 * // with class name.
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 String name = backend.rti.getRawTypeRepresentation(type); 1057 String name = backend.rti.getRawTypeRepresentation(type);
1009 addIdentifier(name); 1058 addIdentifier(name);
1010 } 1059 }
1011 1060
1012 visitInterceptor(InterceptorConstant constant) { 1061 visitInterceptor(InterceptorConstant constant) {
1013 addRoot(constant.dispatchedType.element.name.slowToString()); 1062 addRoot(constant.dispatchedType.element.name.slowToString());
1014 add('methods'); 1063 add('methods');
1015 } 1064 }
1016 } 1065 }
1017 1066
1018
1019 /** 1067 /**
1020 * Generates canonical hash values for [Constant]s. 1068 * Generates canonical hash values for [Constant]s.
1021 * 1069 *
1022 * Unfortunately, [Constant.hashCode] is not stable under minor perturbations, 1070 * Unfortunately, [Constant.hashCode] is not stable under minor perturbations,
1023 * so it can't be used for generating names. This hasher keeps consistency 1071 * so it can't be used for generating names. This hasher keeps consistency
1024 * between runs by basing hash values of the names of elements, rather than 1072 * between runs by basing hash values of the names of elements, rather than
1025 * their hashCodes. 1073 * their hashCodes.
1026 */ 1074 */
1027 class ConstantCanonicalHasher implements ConstantVisitor<int> { 1075 class ConstantCanonicalHasher implements ConstantVisitor<int> {
1028 1076
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 hash = hash ^ (hash >> 6); 1202 hash = hash ^ (hash >> 6);
1155 return hash; 1203 return hash;
1156 } 1204 }
1157 1205
1158 static int _finish(int hash) { 1206 static int _finish(int hash) {
1159 hash = _MASK & (hash + (((_MASK >> 3) & hash) << 3)); 1207 hash = _MASK & (hash + (((_MASK >> 3) & hash) << 3));
1160 hash = hash & (hash >> 11); 1208 hash = hash & (hash >> 11);
1161 return _MASK & (hash + (((_MASK >> 15) & hash) << 15)); 1209 return _MASK & (hash + (((_MASK >> 15) & hash) << 15));
1162 } 1210 }
1163 } 1211 }
1212
1213 class FunctionTypeNamer extends DartTypeVisitor {
1214 StringBuffer sb;
1215
1216 String computeName(DartType type) {
1217 sb = new StringBuffer();
1218 visit(type);
1219 return sb.toString();
1220 }
1221
1222 visit(DartType type) {
1223 type.accept(this, null);
1224 }
1225
1226 visitType(DartType type, _) {
1227 sb.write(type.name.slowToString());
1228 }
1229
1230 visitFunctionType(FunctionType type, _) {
1231 visit(type.returnType);
1232 sb.write('_');
1233 for (Link<DartType> link = type.parameterTypes;
1234 !link.isEmpty;
1235 link = link.tail) {
1236 sb.write('_');
1237 visit(link.head);
1238 }
1239 bool first = false;
1240 for (Link<DartType> link = type.optionalParameterTypes;
1241 !link.isEmpty;
1242 link = link.tail) {
1243 if (!first) {
1244 sb.write('_');
1245 }
1246 sb.write('_');
1247 visit(link.head);
1248 first = true;
1249 }
1250 if (!type.namedParameterTypes.isEmpty) {
1251 first = false;
1252 for (Link<DartType> link = type.namedParameterTypes;
1253 !link.isEmpty;
1254 link = link.tail) {
1255 if (!first) {
1256 sb.write('_');
1257 }
1258 sb.write('_');
1259 visit(link.head);
1260 first = true;
1261 }
1262 }
1263 }
1264 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698