Index: sdk/lib/_internal/js_runtime/lib/interceptors.dart |
diff --git a/sdk/lib/_internal/js_runtime/lib/interceptors.dart b/sdk/lib/_internal/js_runtime/lib/interceptors.dart |
index b13d79a3fa5609ce23919a09da2cbfd2a282d771..25fbb1175176a19ac42e00a37564f76a63b2c791 100644 |
--- a/sdk/lib/_internal/js_runtime/lib/interceptors.dart |
+++ b/sdk/lib/_internal/js_runtime/lib/interceptors.dart |
@@ -21,6 +21,7 @@ import 'dart:_js_helper' show allMatchesInStringUnchecked, |
checkString, |
defineProperty, |
diagnoseIndexError, |
+ getIsolateAffinityTag, |
getRuntimeType, |
initNativeDispatch, |
initNativeDispatchFlag, |
@@ -39,6 +40,7 @@ import 'dart:_js_helper' show allMatchesInStringUnchecked, |
StringMatch, |
firstMatchAfter, |
NoInline; |
+ |
import 'dart:_foreign_helper' show |
JS, |
JS_EFFECT, |
@@ -51,6 +53,9 @@ part 'js_array.dart'; |
part 'js_number.dart'; |
part 'js_string.dart'; |
+final String DART_CLOSURE_PROPERTY_NAME = |
+ getIsolateAffinityTag(r'_$dart_dartClosure'); |
+ |
String _symbolToString(Symbol symbol) => _symbol_dev.Symbol.getName(symbol); |
_symbolMapToStringMap(Map<Symbol, dynamic> map) { |
@@ -169,6 +174,9 @@ getNativeInterceptor(object) { |
// are 'plain' Objects. This test could be simplified and the dispatch path |
// be faster if Object.prototype was pre-patched with a non-leaf dispatch |
// record. |
+ if (JS('bool', 'typeof # == "function"', object)) { |
+ return JS_INTERCEPTOR_CONSTANT(JavaScriptFunction); |
+ } |
var proto = JS('', 'Object.getPrototypeOf(#)', object); |
if (JS('bool', '# == null || # === Object.prototype', proto, proto)) { |
return JS_INTERCEPTOR_CONSTANT(PlainJavaScriptObject); |
@@ -393,13 +401,18 @@ abstract class JSObject { |
* Interceptor base class for JavaScript objects not recognized as some more |
* specific native type. |
*/ |
-abstract class JavaScriptObject extends Interceptor implements JSObject { |
+class JavaScriptObject extends Interceptor implements JSObject { |
const JavaScriptObject(); |
// It would be impolite to stash a property on the object. |
int get hashCode => 0; |
Type get runtimeType => JSObject; |
+ |
+ /** |
+ * Returns the result of the JavaScript objects `toString` method. |
+ */ |
+ String toString() => JS('String', 'String(#)', this); |
} |
@@ -420,6 +433,19 @@ class PlainJavaScriptObject extends JavaScriptObject { |
*/ |
class UnknownJavaScriptObject extends JavaScriptObject { |
const UnknownJavaScriptObject(); |
+} |
- String toString() => JS('String', 'String(#)', this); |
+/** |
+ * Interceptor for JavaScript function objects and Dart functions that have |
+ * been converted to JavaScript functions. |
+ * These interceptor methods are not always used as the JavaScript function |
+ * object has also been mangled to support Dart function calling conventions. |
+ */ |
+class JavaScriptFunction extends JavaScriptObject implements Function { |
+ const JavaScriptFunction(); |
+ |
+ String toString() { |
+ var dartClosure = JS('', '#.#', this, DART_CLOSURE_PROPERTY_NAME); |
+ return dartClosure == null ? super.toString() : dartClosure.toString(); |
+ } |
} |