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

Side by Side Diff: sdk/lib/_internal/js_runtime/lib/js_helper.dart

Issue 1362553002: dart2js runtime: Harden objectTypeName. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 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 | tests/compiler/dart2js_native/error_safeToString_test.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) 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 _js_helper; 5 library _js_helper;
6 6
7 import 'dart:_js_embedded_names' show 7 import 'dart:_js_embedded_names' show
8 DEFERRED_LIBRARY_URIS, 8 DEFERRED_LIBRARY_URIS,
9 DEFERRED_LIBRARY_HASHES, 9 DEFERRED_LIBRARY_HASHES,
10 GET_TYPE_FROM_NAME, 10 GET_TYPE_FROM_NAME,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 DART_CLOSURE_TO_JS, 42 DART_CLOSURE_TO_JS,
43 JS, 43 JS,
44 JS_BUILTIN, 44 JS_BUILTIN,
45 JS_CALL_IN_ISOLATE, 45 JS_CALL_IN_ISOLATE,
46 JS_CONST, 46 JS_CONST,
47 JS_CURRENT_ISOLATE_CONTEXT, 47 JS_CURRENT_ISOLATE_CONTEXT,
48 JS_EFFECT, 48 JS_EFFECT,
49 JS_EMBEDDED_GLOBAL, 49 JS_EMBEDDED_GLOBAL,
50 JS_GET_FLAG, 50 JS_GET_FLAG,
51 JS_GET_NAME, 51 JS_GET_NAME,
52 JS_INTERCEPTOR_CONSTANT,
52 JS_STRING_CONCAT, 53 JS_STRING_CONCAT,
53 RAW_DART_FUNCTION_REF; 54 RAW_DART_FUNCTION_REF;
54 55
55 import 'dart:_interceptors'; 56 import 'dart:_interceptors';
56 import 'dart:_internal' as _symbol_dev; 57 import 'dart:_internal' as _symbol_dev;
57 import 'dart:_internal' show 58 import 'dart:_internal' show
58 EfficientLength, 59 EfficientLength,
59 MappedIterable, 60 MappedIterable,
60 IterableElementError; 61 IterableElementError;
61 62
(...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 /// constructor of the given class. 839 /// constructor of the given class.
839 static String formatType(String className, List typeArguments) { 840 static String formatType(String className, List typeArguments) {
840 return unmangleAllIdentifiersIfPreservedAnyways 841 return unmangleAllIdentifiersIfPreservedAnyways
841 ('$className${joinArguments(typeArguments, 0)}'); 842 ('$className${joinArguments(typeArguments, 0)}');
842 } 843 }
843 844
844 /// Returns the type of [object] as a string (including type arguments). 845 /// Returns the type of [object] as a string (including type arguments).
845 /// 846 ///
846 /// In minified mode, uses the unminified names if available. 847 /// In minified mode, uses the unminified names if available.
847 static String objectTypeName(Object object) { 848 static String objectTypeName(Object object) {
848 String name = constructorNameFallback(getInterceptor(object)); 849 return formatType(_objectRawTypeName(object), getRuntimeTypeInfo(object));
849 if (name == 'Object') { 850 }
850 // Try to decompile the constructor by turning it into a string and get 851
851 // the name out of that. If the decompiled name is a string containing an 852 static String _objectRawTypeName(Object object) {
852 // identifier, we use that instead of the very generic 'Object'. 853 var interceptor = getInterceptor(object);
853 var decompiled = 854 // The interceptor is either an object (self-intercepting plain Dart class),
854 JS('var', r'#.match(/^\s*function\s*([\w$]*)\s*\(/)[1]', 855 // the prototype of the constructor for an Interceptor class (like
855 JS('var', r'String(#.constructor)', object)); 856 // `JSString.prototype`, `JSNull.prototype`), or an Interceptor object
856 if (decompiled is String) 857 // instance (`const JSString()`, should use `JSString.prototype`).
857 if (JS('bool', r'/^\w+$/.test(#)', decompiled)) 858 //
858 name = decompiled; 859 // These all should have a `constructor` property with a `name` property.
860 String name;
861 var interceptorConstructor = JS('', '#.constructor', interceptor);
862 if (JS('bool', 'typeof # == "function"', interceptorConstructor)) {
863 var interceptorConstructorName = JS('', '#.name', interceptorConstructor);
864 if (interceptorConstructorName is String) {
865 name = interceptorConstructorName;
866 }
859 } 867 }
868
869 if (name == null ||
870 identical(interceptor,
871 JS_INTERCEPTOR_CONSTANT(UnknownJavaScriptObject)) ||
872 identical(interceptor, JS_INTERCEPTOR_CONSTANT(Interceptor))) {
873 // Try to do better. If we do not find something better, leave the name
874 // as 'UnknownJavaScriptObject' or 'Interceptor' (or the minified name).
875 //
876 // When we get here via the UnknownJavaScriptObject test (for JavaScript
877 // objects from outside the program), the object's constructor has a
878 // better name that 'UnknownJavaScriptObject'.
879 //
880 // When we get here the Interceptor test (for Native classes that are
881 // declared in the Dart program but have been 'folded' into Interceptor),
882 // the native class's constructor name is better than the generic
883 // 'Interceptor' (an abstract class).
884
885 // Try the [constructorNameFallback]. This gets the constructor name for
886 // any browser (used by [getNativeInterceptor]).
887 String dispatchName = constructorNameFallback(object);
888 if (name == null) name = dispatchName;
889 if (dispatchName == 'Object') {
890 // Try to decompile the constructor by turning it into a string and get
891 // the name out of that. If the decompiled name is a string containing
892 // an identifier, we use that instead of the very generic 'Object'.
893 var objectConstructor = JS('', '#.constructor', object);
894 if (JS('bool', 'typeof # == "function"', objectConstructor)) {
895 var decompiledName =
896 JS('var', r'#.match(/^\s*function\s*([\w$]*)\s*\(/)[1]',
897 JS('var', r'String(#)', objectConstructor));
898 if (decompiledName is String &&
899 JS('bool', r'/^\w+$/.test(#)', decompiledName)) {
900 name = decompiledName;
901 }
902 }
903 } else {
904 name = dispatchName;
905 }
906 }
907
860 // TODO(kasperl): If the namer gave us a fresh global name, we may 908 // TODO(kasperl): If the namer gave us a fresh global name, we may
861 // want to remove the numeric suffix that makes it unique too. 909 // want to remove the numeric suffix that makes it unique too.
862 if (name.length > 1 && identical(name.codeUnitAt(0), DOLLAR_CHAR_VALUE)) { 910 if (name.length > 1 && identical(name.codeUnitAt(0), DOLLAR_CHAR_VALUE)) {
863 name = name.substring(1); 911 name = name.substring(1);
864 } 912 }
865 return formatType(name, getRuntimeTypeInfo(object)); 913 return name;
866 } 914 }
867 915
868 /// In minified mode, uses the unminified names if available. 916 /// In minified mode, uses the unminified names if available.
869 static String objectToHumanReadableString(Object object) { 917 static String objectToHumanReadableString(Object object) {
870 String name = objectTypeName(object); 918 String name = objectTypeName(object);
871 return "Instance of '$name'"; 919 return "Instance of '$name'";
872 } 920 }
873 921
874 static num dateNow() => JS('int', r'Date.now()'); 922 static num dateNow() => JS('int', r'Date.now()');
875 923
(...skipping 3145 matching lines...) Expand 10 before | Expand all | Expand 10 after
4021 // unneeded code. 4069 // unneeded code.
4022 class _UnreachableError extends AssertionError { 4070 class _UnreachableError extends AssertionError {
4023 _UnreachableError(); 4071 _UnreachableError();
4024 String toString() => "Assertion failed: Reached dead code"; 4072 String toString() => "Assertion failed: Reached dead code";
4025 } 4073 }
4026 4074
4027 @NoInline() 4075 @NoInline()
4028 void assertUnreachable() { 4076 void assertUnreachable() {
4029 throw new _UnreachableError(); 4077 throw new _UnreachableError();
4030 } 4078 }
OLDNEW
« no previous file with comments | « no previous file | tests/compiler/dart2js_native/error_safeToString_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698