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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/compiler/dart2js_native/error_safeToString_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/_internal/js_runtime/lib/js_helper.dart
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index 663121a605f99407676a7468c2bd6fe0ce0044ee..000753264a5a14a5d0146b9800c9770b9ec1c2c5 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -49,6 +49,7 @@ import 'dart:_foreign_helper' show
JS_EMBEDDED_GLOBAL,
JS_GET_FLAG,
JS_GET_NAME,
+ JS_INTERCEPTOR_CONSTANT,
JS_STRING_CONCAT,
RAW_DART_FUNCTION_REF;
@@ -845,24 +846,71 @@ class Primitives {
///
/// In minified mode, uses the unminified names if available.
static String objectTypeName(Object object) {
- String name = constructorNameFallback(getInterceptor(object));
- if (name == 'Object') {
- // Try to decompile the constructor by turning it into a string and get
- // the name out of that. If the decompiled name is a string containing an
- // identifier, we use that instead of the very generic 'Object'.
- var decompiled =
- JS('var', r'#.match(/^\s*function\s*([\w$]*)\s*\(/)[1]',
- JS('var', r'String(#.constructor)', object));
- if (decompiled is String)
- if (JS('bool', r'/^\w+$/.test(#)', decompiled))
- name = decompiled;
+ return formatType(_objectRawTypeName(object), getRuntimeTypeInfo(object));
+ }
+
+ static String _objectRawTypeName(Object object) {
+ var interceptor = getInterceptor(object);
+ // The interceptor is either an object (self-intercepting plain Dart class),
+ // the prototype of the constructor for an Interceptor class (like
+ // `JSString.prototype`, `JSNull.prototype`), or an Interceptor object
+ // instance (`const JSString()`, should use `JSString.prototype`).
+ //
+ // These all should have a `constructor` property with a `name` property.
+ String name;
+ var interceptorConstructor = JS('', '#.constructor', interceptor);
+ if (JS('bool', 'typeof # == "function"', interceptorConstructor)) {
+ var interceptorConstructorName = JS('', '#.name', interceptorConstructor);
+ if (interceptorConstructorName is String) {
+ name = interceptorConstructorName;
+ }
+ }
+
+ if (name == null ||
+ identical(interceptor,
+ JS_INTERCEPTOR_CONSTANT(UnknownJavaScriptObject)) ||
+ identical(interceptor, JS_INTERCEPTOR_CONSTANT(Interceptor))) {
+ // Try to do better. If we do not find something better, leave the name
+ // as 'UnknownJavaScriptObject' or 'Interceptor' (or the minified name).
+ //
+ // When we get here via the UnknownJavaScriptObject test (for JavaScript
+ // objects from outside the program), the object's constructor has a
+ // better name that 'UnknownJavaScriptObject'.
+ //
+ // When we get here the Interceptor test (for Native classes that are
+ // declared in the Dart program but have been 'folded' into Interceptor),
+ // the native class's constructor name is better than the generic
+ // 'Interceptor' (an abstract class).
+
+ // Try the [constructorNameFallback]. This gets the constructor name for
+ // any browser (used by [getNativeInterceptor]).
+ String dispatchName = constructorNameFallback(object);
+ if (name == null) name = dispatchName;
+ if (dispatchName == 'Object') {
+ // Try to decompile the constructor by turning it into a string and get
+ // the name out of that. If the decompiled name is a string containing
+ // an identifier, we use that instead of the very generic 'Object'.
+ var objectConstructor = JS('', '#.constructor', object);
+ if (JS('bool', 'typeof # == "function"', objectConstructor)) {
+ var decompiledName =
+ JS('var', r'#.match(/^\s*function\s*([\w$]*)\s*\(/)[1]',
+ JS('var', r'String(#)', objectConstructor));
+ if (decompiledName is String &&
+ JS('bool', r'/^\w+$/.test(#)', decompiledName)) {
+ name = decompiledName;
+ }
+ }
+ } else {
+ name = dispatchName;
+ }
}
+
// TODO(kasperl): If the namer gave us a fresh global name, we may
// want to remove the numeric suffix that makes it unique too.
if (name.length > 1 && identical(name.codeUnitAt(0), DOLLAR_CHAR_VALUE)) {
name = name.substring(1);
}
- return formatType(name, getRuntimeTypeInfo(object));
+ return name;
}
/// In minified mode, uses the unminified names if available.
« 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