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

Unified Diff: sdk/lib/_internal/lib/native_helper.dart

Issue 15026006: Support for extending native classes (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 4 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
Index: sdk/lib/_internal/lib/native_helper.dart
diff --git a/sdk/lib/_internal/lib/native_helper.dart b/sdk/lib/_internal/lib/native_helper.dart
index 5c311f4f69196f764bb7acc1d9aec14534964db1..952f903a8c42ab6a4397c8c1560e6c9eaf129f44 100644
--- a/sdk/lib/_internal/lib/native_helper.dart
+++ b/sdk/lib/_internal/lib/native_helper.dart
@@ -240,6 +240,10 @@ var interceptorsByTag;
/// A JavaScript object mapping tags to `true` or `false`.
var leafTags;
+/// A JavaScript list mapping subclass interceptor constructors to the native
+/// superclass tag.
+var interceptorToTag;
+
/**
* Associates tags with an interceptor. Called from generated code. The tags
* are all 'leaf' tags representing classes that have no subclasses with
@@ -260,6 +264,28 @@ void defineNativeMethodsNonleaf(String tags, interceptorClass) {
defineNativeMethodsCommon(tags, interceptorClass, false);
}
+/**
+ * Associates tags with an interceptor. Called from generated code. The tags
+ * are all non-'leaf' tags, representing classes that have a user defined
+ * subclass that requires additional dispatch. [subclassInterceptorClasses] is a
+ * list of interceptor classes (i.e. constructors) for the user defined
+ * subclasses.
+ */
+void defineNativeMethodsExtended(String tags, interceptorClass,
+ subclassInterceptorClasses) {
+ if (interceptorToTag == null) {
+ interceptorToTag = [];
+ }
+ List classes = JS('JSFixedArray', '#', subclassInterceptorClasses);
+ for (int i = 0; i < classes.length; i++) {
+ interceptorToTag.add(classes[i]);
+ // 'tags' is a single tag.
+ interceptorToTag.add(tags);
+ }
+
+ defineNativeMethodsCommon(tags, interceptorClass, false);
+}
+
void defineNativeMethodsCommon(String tags, var interceptorClass, bool isLeaf) {
var methods = JS('', '#.prototype', interceptorClass);
if (interceptorsByTag == null) interceptorsByTag = JS('=Object', '{}');
@@ -280,6 +306,14 @@ void defineNativeMethodsFinish() {
// classes over unknown.
}
+String findDispatchTagForInterceptorClass(interceptorClassConstructor) {
+ if (interceptorToTag == null) return null;
+ int i =
+ JS('int', '#.indexOf(#)', interceptorToTag, interceptorClassConstructor);
+ if (i < 0) return null;
+ return JS('', '#[#]', interceptorToTag, i + 1);
+}
+
lookupInterceptor(var hasOwnPropertyFunction, String tag) {
var map = interceptorsByTag;
if (map == null) return null;
@@ -313,11 +347,23 @@ lookupDispatchRecord(obj) {
var isLeaf =
(leafTags != null) && JS('bool', '(#[#]) === true', leafTags, tag);
if (isLeaf) {
- var fieldName = JS_IS_INDEXABLE_FIELD_NAME();
- bool indexability = JS('bool', r'!!#[#]', interceptor, fieldName);
- return makeDispatchRecord(interceptor, false, null, indexability);
+ return makeLeafDispatchRecord(interceptor);
} else {
var proto = JS('', 'Object.getPrototypeOf(#)', obj);
return makeDispatchRecord(interceptor, proto, null, null);
}
}
+
+makeLeafDispatchRecord(interceptor) {
+ var fieldName = JS_IS_INDEXABLE_FIELD_NAME();
+ bool indexability = JS('bool', r'!!#[#]', interceptor, fieldName);
+ return makeDispatchRecord(interceptor, false, null, indexability);
+}
+
+/**
+ * [proto] should have no shadowing prototypes that are not also assigned a
+ * dispatch rescord.
+ */
+setNativeSubclassDispatchRecord(proto, interceptor) {
+ setDispatchProperty(proto, makeLeafDispatchRecord(interceptor));
+}

Powered by Google App Engine
This is Rietveld 408576698