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

Unified Diff: sdk/lib/_internal/js_runtime/lib/interceptors.dart

Issue 2379173002: Add native_testing library to mock @Native classes (Closed)
Patch Set: xxx Created 4 years, 1 month 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 | sdk/lib/_internal/js_runtime/lib/native_helper.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/interceptors.dart
diff --git a/sdk/lib/_internal/js_runtime/lib/interceptors.dart b/sdk/lib/_internal/js_runtime/lib/interceptors.dart
index 23025ad578cc34276949080428a92a0e7b49fcab..7246c406edf480acb8857ee3b5d3d439082cdc11 100644
--- a/sdk/lib/_internal/js_runtime/lib/interceptors.dart
+++ b/sdk/lib/_internal/js_runtime/lib/interceptors.dart
@@ -168,24 +168,69 @@ getNativeInterceptor(object) {
}
}
- var interceptor = lookupAndCacheInterceptor(object);
- if (interceptor == null) {
- // JavaScript Objects created via object literals and `Object.create(null)`
- // 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);
- } else {
- return JS_INTERCEPTOR_CONSTANT(UnknownJavaScriptObject);
- }
+ // Check for cached UnknownJavaScriptObject. This avoids doing the slow
+ // dispatch-record based lookup for repeated js-interop classes.
+ var constructor = JS('', '#.constructor', object);
+ var interceptor = lookupInterceptorByConstructor(constructor);
+ if (interceptor != null) return interceptor;
+
+ // This takes care of dispatch-record based caching, but not constructor based
+ // caching of [UnknownJavaScriptObject]s.
+ interceptor = lookupAndCacheInterceptor(object);
+ if (interceptor != null) return interceptor;
+
+ // JavaScript Objects created via object literals and `Object.create(null)`
+ // 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)) {
+ interceptor = JS_INTERCEPTOR_CONSTANT(JavaScriptFunction);
+ // TODO(sra): Investigate caching on `Function`. It might be impossible if
+ // some HTML embedded objects on some browsers are (still) JS functions.
+ return interceptor;
+ }
+ var proto = JS('', 'Object.getPrototypeOf(#)', object);
+ if (JS('bool', '# == null', proto)) {
+ // Nowhere to cache output.
+ return JS_INTERCEPTOR_CONSTANT(PlainJavaScriptObject);
+ }
+ interceptor = JS_INTERCEPTOR_CONSTANT(UnknownJavaScriptObject);
+ if (JS('bool', '# === Object.prototype', proto)) {
+ interceptor = JS_INTERCEPTOR_CONSTANT(PlainJavaScriptObject);
+ // TODO(sra): Investigate caching on 'Object'. It might be impossible if
+ // some native class is plain Object (e.g. like Firefox's ImageData).
+ return interceptor;
}
+ if (JS('bool', 'typeof # == "function"', constructor)) {
+ cacheInterceptorOnConstructor(constructor, interceptor);
+ return interceptor;
+ }
+ return JS_INTERCEPTOR_CONSTANT(UnknownJavaScriptObject);
+}
+
+
+// A JS String or Symbol.
+final JS_INTEROP_INTERCEPTOR_TAG = getIsolateAffinityTag(r'_$dart_js');
+
+lookupInterceptorByConstructor(constructor) {
+ return constructor == null
+ ? null
+ : JS('', '#[#]', constructor, JS_INTEROP_INTERCEPTOR_TAG);
+}
+
+void cacheInterceptorOnConstructor(constructor, interceptor) {
+ defineProperty(constructor, JS_INTEROP_INTERCEPTOR_TAG, interceptor);
+}
+
+var constructorToInterceptor =
+ JS('', 'typeof(self.WeakMap) == "undefined" ? new Map() : new WeakMap()');
+
+XlookupInterceptorByConstructor(constructor) {
+ return JS('', '#.get(#)', constructorToInterceptor, constructor);
+}
- return interceptor;
+void XcacheInterceptorOnConstructor(constructor, interceptor) {
+ JS('', '#.set(#, #)', constructorToInterceptor, constructor, interceptor);
}
/**
« no previous file with comments | « no previous file | sdk/lib/_internal/js_runtime/lib/native_helper.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698