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

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

Issue 206193002: Remove cancel and make crash exit with code 253. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments. Created 6 years, 9 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 native; 5 library native;
6 6
7 import 'dart:collection' show Queue; 7 import 'dart:collection' show Queue;
8 import 'dart2jslib.dart'; 8 import 'dart2jslib.dart';
9 import 'dart_types.dart'; 9 import 'dart_types.dart';
10 import 'elements/elements.dart'; 10 import 'elements/elements.dart';
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 ClassElement get annotationJsNameClass { 281 ClassElement get annotationJsNameClass {
282 findAnnotationClasses(); 282 findAnnotationClasses();
283 return _annotationJsNameClass; 283 return _annotationJsNameClass;
284 } 284 }
285 285
286 void findAnnotationClasses() { 286 void findAnnotationClasses() {
287 if (_annotationCreatesClass != null) return; 287 if (_annotationCreatesClass != null) return;
288 ClassElement find(name) { 288 ClassElement find(name) {
289 Element e = compiler.findHelper(name); 289 Element e = compiler.findHelper(name);
290 if (e == null || e is! ClassElement) { 290 if (e == null || e is! ClassElement) {
291 compiler.cancel("Could not find implementation class '${name}'"); 291 compiler.internalError(NO_LOCATION_SPANNABLE,
292 "Could not find implementation class '${name}'.");
292 } 293 }
293 return e; 294 return e;
294 } 295 }
295 _annotationCreatesClass = find('Creates'); 296 _annotationCreatesClass = find('Creates');
296 _annotationReturnsClass = find('Returns'); 297 _annotationReturnsClass = find('Returns');
297 _annotationJsNameClass = find('JSName'); 298 _annotationJsNameClass = find('JSName');
298 } 299 }
299 300
300 /// Returns the JSName annotation string or `null` if no JSName annotation is 301 /// Returns the JSName annotation string or `null` if no JSName annotation is
301 /// present. 302 /// present.
302 String findJsNameFromAnnotation(Element element) { 303 String findJsNameFromAnnotation(Element element) {
303 String name = null; 304 String name = null;
304 ClassElement annotationClass = annotationJsNameClass; 305 ClassElement annotationClass = annotationJsNameClass;
305 for (Link<MetadataAnnotation> link = element.metadata; 306 for (Link<MetadataAnnotation> link = element.metadata;
306 !link.isEmpty; 307 !link.isEmpty;
307 link = link.tail) { 308 link = link.tail) {
308 MetadataAnnotation annotation = link.head.ensureResolved(compiler); 309 MetadataAnnotation annotation = link.head.ensureResolved(compiler);
309 var value = annotation.value; 310 var value = annotation.value;
310 if (value is! ConstructedConstant) continue; 311 if (value is! ConstructedConstant) continue;
311 if (value.type is! InterfaceType) continue; 312 if (value.type is! InterfaceType) continue;
312 if (!identical(value.type.element, annotationClass)) continue; 313 if (!identical(value.type.element, annotationClass)) continue;
313 314
314 var fields = value.fields; 315 var fields = value.fields;
315 // TODO(sra): Better validation of the constant. 316 // TODO(sra): Better validation of the constant.
316 if (fields.length != 1 || fields[0] is! StringConstant) { 317 if (fields.length != 1 || fields[0] is! StringConstant) {
317 PartialMetadataAnnotation partial = annotation; 318 PartialMetadataAnnotation partial = annotation;
318 compiler.cancel( 319 compiler.internalError(annotation,
319 'Annotations needs one string: ${partial.parseNode(compiler)}'); 320 'Annotations needs one string: ${partial.parseNode(compiler)}');
320 } 321 }
321 String specString = fields[0].toDartString().slowToString(); 322 String specString = fields[0].toDartString().slowToString();
322 if (name == null) { 323 if (name == null) {
323 name = specString; 324 name = specString;
324 } else { 325 } else {
325 PartialMetadataAnnotation partial = annotation; 326 PartialMetadataAnnotation partial = annotation;
326 compiler.cancel( 327 compiler.internalError(annotation,
327 'Too many JSName annotations: ${partial.parseNode(compiler)}'); 328 'Too many JSName annotations: ${partial.parseNode(compiler)}');
328 } 329 }
329 } 330 }
330 return name; 331 return name;
331 } 332 }
332 333
333 enqueueClass(ClassElement classElement, cause) { 334 enqueueClass(ClassElement classElement, cause) {
334 assert(unusedClasses.contains(classElement)); 335 assert(unusedClasses.contains(classElement));
335 unusedClasses.remove(classElement); 336 unusedClasses.remove(classElement);
336 pendingClasses.add(classElement); 337 pendingClasses.add(classElement);
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 758
758 static NativeBehavior ofJsCall(Send jsCall, Compiler compiler, resolver) { 759 static NativeBehavior ofJsCall(Send jsCall, Compiler compiler, resolver) {
759 // The first argument of a JS-call is a string encoding various attributes 760 // The first argument of a JS-call is a string encoding various attributes
760 // of the code. 761 // of the code.
761 // 762 //
762 // 'Type1|Type2'. A union type. 763 // 'Type1|Type2'. A union type.
763 // '=Object'. A JavaScript Object, no subtype. 764 // '=Object'. A JavaScript Object, no subtype.
764 765
765 var argNodes = jsCall.arguments; 766 var argNodes = jsCall.arguments;
766 if (argNodes.isEmpty) { 767 if (argNodes.isEmpty) {
767 compiler.cancel("JS expression has no type", node: jsCall); 768 compiler.internalError(jsCall, "JS expression has no type.");
768 } 769 }
769 770
770 var code = argNodes.tail.head; 771 var code = argNodes.tail.head;
771 if (code is !StringNode || code.isInterpolation) { 772 if (code is !StringNode || code.isInterpolation) {
772 compiler.cancel('JS code must be a string literal', node: code); 773 compiler.internalError(code, 'JS code must be a string literal.');
773 } 774 }
774 775
775 LiteralString specLiteral = argNodes.head.asLiteralString(); 776 LiteralString specLiteral = argNodes.head.asLiteralString();
776 if (specLiteral == null) { 777 if (specLiteral == null) {
777 // TODO(sra): We could accept a type identifier? e.g. JS(bool, '1<2'). It 778 // TODO(sra): We could accept a type identifier? e.g. JS(bool, '1<2'). It
778 // is not very satisfactory because it does not work for void, dynamic. 779 // is not very satisfactory because it does not work for void, dynamic.
779 compiler.cancel("Unexpected JS first argument", node: argNodes.head); 780 compiler.internalError(argNodes.head, "Unexpected JS first argument.");
780 } 781 }
781 782
782 var behavior = new NativeBehavior(); 783 var behavior = new NativeBehavior();
783 behavior.codeAst = js.js.parseForeignJS(code.dartString.slowToString()); 784 behavior.codeAst = js.js.parseForeignJS(code.dartString.slowToString());
784 new SideEffectsVisitor(behavior.sideEffects).visit(behavior.codeAst); 785 new SideEffectsVisitor(behavior.sideEffects).visit(behavior.codeAst);
785 786
786 String specString = specLiteral.dartString.slowToString(); 787 String specString = specLiteral.dartString.slowToString();
787 // Various things that are not in fact types. 788 // Various things that are not in fact types.
788 if (specString == 'void') return behavior; 789 if (specString == 'void') return behavior;
789 if (specString == '' || specString == 'var') { 790 if (specString == '' || specString == 'var') {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 MetadataAnnotation annotation = link.head.ensureResolved(compiler); 885 MetadataAnnotation annotation = link.head.ensureResolved(compiler);
885 var value = annotation.value; 886 var value = annotation.value;
886 if (value is! ConstructedConstant) continue; 887 if (value is! ConstructedConstant) continue;
887 if (value.type is! InterfaceType) continue; 888 if (value.type is! InterfaceType) continue;
888 if (!identical(value.type.element, annotationClass)) continue; 889 if (!identical(value.type.element, annotationClass)) continue;
889 890
890 var fields = value.fields; 891 var fields = value.fields;
891 // TODO(sra): Better validation of the constant. 892 // TODO(sra): Better validation of the constant.
892 if (fields.length != 1 || fields[0] is! StringConstant) { 893 if (fields.length != 1 || fields[0] is! StringConstant) {
893 PartialMetadataAnnotation partial = annotation; 894 PartialMetadataAnnotation partial = annotation;
894 compiler.cancel( 895 compiler.internalError(annotation,
895 'Annotations needs one string: ${partial.parseNode(compiler)}'); 896 'Annotations needs one string: ${partial.parseNode(compiler)}');
896 } 897 }
897 String specString = fields[0].toDartString().slowToString(); 898 String specString = fields[0].toDartString().slowToString();
898 for (final typeString in specString.split('|')) { 899 for (final typeString in specString.split('|')) {
899 var type = _parseType(typeString, compiler, lookup, annotation); 900 var type = _parseType(typeString, compiler, lookup, annotation);
900 if (types == null) types = []; 901 if (types == null) types = [];
901 types.add(type); 902 types.add(type);
902 } 903 }
903 } 904 }
904 return types; 905 return types;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 lookup(name), locationNodeOrElement) { 944 lookup(name), locationNodeOrElement) {
944 if (typeString == '=Object') return SpecialType.JsObject; 945 if (typeString == '=Object') return SpecialType.JsObject;
945 if (typeString == 'dynamic') { 946 if (typeString == 'dynamic') {
946 return compiler.types.dynamicType; 947 return compiler.types.dynamicType;
947 } 948 }
948 DartType type = lookup(typeString); 949 DartType type = lookup(typeString);
949 if (type != null) return type; 950 if (type != null) return type;
950 951
951 int index = typeString.indexOf('<'); 952 int index = typeString.indexOf('<');
952 if (index < 1) { 953 if (index < 1) {
953 compiler.cancel("Type '$typeString' not found", 954 compiler.internalError(
954 node: _errorNode(locationNodeOrElement, compiler)); 955 _errorNode(locationNodeOrElement, compiler),
956 "Type '$typeString' not found.");
955 } 957 }
956 type = lookup(typeString.substring(0, index)); 958 type = lookup(typeString.substring(0, index));
957 if (type != null) { 959 if (type != null) {
958 // TODO(sra): Parse type parameters. 960 // TODO(sra): Parse type parameters.
959 return type; 961 return type;
960 } 962 }
961 compiler.cancel("Type '$typeString' not found", 963 compiler.internalError(
962 node: _errorNode(locationNodeOrElement, compiler)); 964 _errorNode(locationNodeOrElement, compiler),
965 "Type '$typeString' not found.");
963 } 966 }
964 967
965 static _errorNode(locationNodeOrElement, compiler) { 968 static _errorNode(locationNodeOrElement, compiler) {
966 if (locationNodeOrElement is Node) return locationNodeOrElement; 969 if (locationNodeOrElement is Node) return locationNodeOrElement;
967 return locationNodeOrElement.parseNode(compiler); 970 return locationNodeOrElement.parseNode(compiler);
968 } 971 }
969 } 972 }
970 973
971 void checkAllowedLibrary(ElementListener listener, Token token) { 974 void checkAllowedLibrary(ElementListener listener, Token token) {
972 LibraryElement currentLibrary = listener.compilationUnitElement.getLibrary(); 975 LibraryElement currentLibrary = listener.compilationUnitElement.getLibrary();
973 if (!currentLibrary.canUseNative) { 976 if (!currentLibrary.canUseNative) {
974 listener.recoverableError("Unexpected token", token: token); 977 listener.recoverableError(token, "Unexpected token");
975 } 978 }
976 } 979 }
977 980
978 Token handleNativeBlockToSkip(Listener listener, Token token) { 981 Token handleNativeBlockToSkip(Listener listener, Token token) {
979 checkAllowedLibrary(listener, token); 982 checkAllowedLibrary(listener, token);
980 token = token.next; 983 token = token.next;
981 if (identical(token.kind, STRING_TOKEN)) { 984 if (identical(token.kind, STRING_TOKEN)) {
982 token = token.next; 985 token = token.next;
983 } 986 }
984 if (identical(token.stringValue, '{')) { 987 if (identical(token.stringValue, '{')) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1073 // No longer supported, this is now done with @JSName('foo') and case 1. 1076 // No longer supported, this is now done with @JSName('foo') and case 1.
1074 // 3) foo() native "return 42"; 1077 // 3) foo() native "return 42";
1075 // hasBody = true 1078 // hasBody = true
1076 bool hasBody = false; 1079 bool hasBody = false;
1077 assert(element.isNative()); 1080 assert(element.isNative());
1078 String nativeMethodName = element.fixedBackendName(); 1081 String nativeMethodName = element.fixedBackendName();
1079 if (nativeBody != null) { 1082 if (nativeBody != null) {
1080 LiteralString jsCode = nativeBody.asLiteralString(); 1083 LiteralString jsCode = nativeBody.asLiteralString();
1081 String str = jsCode.dartString.slowToString(); 1084 String str = jsCode.dartString.slowToString();
1082 if (nativeRedirectionRegExp.hasMatch(str)) { 1085 if (nativeRedirectionRegExp.hasMatch(str)) {
1083 compiler.cancel("Deprecated syntax, use @JSName('name') instead.", 1086 compiler.internalError(
1084 node: nativeBody); 1087 nativeBody, "Deprecated syntax, use @JSName('name') instead.");
1085 } 1088 }
1086 hasBody = true; 1089 hasBody = true;
1087 } 1090 }
1088 1091
1089 if (!hasBody) { 1092 if (!hasBody) {
1090 nativeEmitter.nativeMethods.add(element); 1093 nativeEmitter.nativeMethods.add(element);
1091 } 1094 }
1092 1095
1093 FunctionSignature parameters = element.functionSignature; 1096 FunctionSignature parameters = element.functionSignature;
1094 if (!hasBody) { 1097 if (!hasBody) {
(...skipping 18 matching lines...) Expand all
1113 1116
1114 String foreignParameters = arguments.join(','); 1117 String foreignParameters = arguments.join(',');
1115 String nativeMethodCall; 1118 String nativeMethodCall;
1116 if (element.kind == ElementKind.FUNCTION) { 1119 if (element.kind == ElementKind.FUNCTION) {
1117 nativeMethodCall = '$receiver$nativeMethodName($foreignParameters)'; 1120 nativeMethodCall = '$receiver$nativeMethodName($foreignParameters)';
1118 } else if (element.kind == ElementKind.GETTER) { 1121 } else if (element.kind == ElementKind.GETTER) {
1119 nativeMethodCall = '$receiver$nativeMethodName'; 1122 nativeMethodCall = '$receiver$nativeMethodName';
1120 } else if (element.kind == ElementKind.SETTER) { 1123 } else if (element.kind == ElementKind.SETTER) {
1121 nativeMethodCall = '$receiver$nativeMethodName = $foreignParameters'; 1124 nativeMethodCall = '$receiver$nativeMethodName = $foreignParameters';
1122 } else { 1125 } else {
1123 builder.compiler.internalError('unexpected kind: "${element.kind}"', 1126 builder.compiler.internalError(element,
1124 element: element); 1127 'Unexpected kind: "${element.kind}".');
1125 } 1128 }
1126 1129
1127 builder.push(new HForeign(js.js(nativeMethodCall), backend.dynamicType, 1130 builder.push(new HForeign(js.js(nativeMethodCall), backend.dynamicType,
1128 inputs, effects: new SideEffects())); 1131 inputs, effects: new SideEffects()));
1129 builder.close(new HReturn(builder.pop())).addSuccessor(builder.graph.exit); 1132 builder.close(new HReturn(builder.pop())).addSuccessor(builder.graph.exit);
1130 } else { 1133 } else {
1131 if (parameters.parameterCount != 0) { 1134 if (parameters.parameterCount != 0) {
1132 compiler.cancel( 1135 compiler.internalError(nativeBody,
1133 'native "..." syntax is restricted to functions with zero parameters', 1136 'native "..." syntax is restricted to '
1134 node: nativeBody); 1137 'functions with zero parameters.');
1135 } 1138 }
1136 LiteralString jsCode = nativeBody.asLiteralString(); 1139 LiteralString jsCode = nativeBody.asLiteralString();
1137 builder.push(new HForeign.statement( 1140 builder.push(new HForeign.statement(
1138 new js.LiteralStatement(jsCode.dartString.slowToString()), 1141 new js.LiteralStatement(jsCode.dartString.slowToString()),
1139 <HInstruction>[], 1142 <HInstruction>[],
1140 new SideEffects(), 1143 new SideEffects(),
1141 null, 1144 null,
1142 backend.dynamicType)); 1145 backend.dynamicType));
1143 } 1146 }
1144 } 1147 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698