Index: runtime/vm/class_table.cc |
=================================================================== |
--- runtime/vm/class_table.cc (revision 11005) |
+++ runtime/vm/class_table.cc (working copy) |
@@ -96,4 +96,79 @@ |
} |
} |
+ |
+// Returns true if the given array of cids contains the given cid. |
+static bool ContainsCid(ZoneGrowableArray<intptr_t>* cids, intptr_t cid) { |
+ for (intptr_t i = 0; i < cids->length(); i++) { |
+ if ((*cids)[i] == cid) { |
+ return true; |
+ } |
+ } |
+ return false; |
+} |
+ |
+ |
+// Recursively collect direct and indirect subclass ids of cls. |
+static void CollectSubclassIds(ZoneGrowableArray<intptr_t>* cids, |
+ const Class& cls) { |
+ const GrowableObjectArray& cls_direct_subclasses = |
+ GrowableObjectArray::Handle(cls.direct_subclasses()); |
+ if (cls_direct_subclasses.IsNull()) { |
+ return; |
+ } |
+ Class& direct_subclass = Class::Handle(); |
+ for (intptr_t i = 0; i < cls_direct_subclasses.Length(); i++) { |
+ direct_subclass ^= cls_direct_subclasses.At(i); |
+ intptr_t direct_subclass_id = direct_subclass.id(); |
+ if (!ContainsCid(cids, direct_subclass_id)) { |
+ cids->Add(direct_subclass_id); |
+ CollectSubclassIds(cids, direct_subclass); |
+ } |
+ } |
+} |
+ |
+ |
+ZoneGrowableArray<intptr_t>* ClassTable::GetSubclassIdsOf(intptr_t cid) const { |
+ const Class& cls = Class::Handle(At(cid)); |
+ ASSERT(!cls.IsNull()); |
+ // TODO(regis): Replace assert below with ASSERT(cid > kDartObjectCid). |
+ ASSERT(!cls.IsObjectClass()); |
+ ZoneGrowableArray<intptr_t>* ids = new ZoneGrowableArray<intptr_t>(); |
+ CollectSubclassIds(ids, cls); |
+ return ids; |
+} |
+ |
+ |
+ZoneGrowableArray<Function*>* ClassTable::GetNamedInstanceFunctionsOf( |
+ const ZoneGrowableArray<intptr_t>& cids, |
+ const String& function_name) const { |
+ ASSERT(!function_name.IsNull()); |
+ ZoneGrowableArray<Function*>* functions = new ZoneGrowableArray<Function*>(); |
+ Class& cls = Class::Handle(); |
+ Function& cls_function = Function::Handle(); |
+ for (intptr_t i = 0; i < cids.length(); i++) { |
+ const intptr_t cid = cids[i]; |
+ cls = At(cid); |
+ // TODO(regis): Replace assert below with ASSERT(cid > kDartObjectCid). |
+ ASSERT(!cls.IsObjectClass()); |
+ cls_function = cls.LookupDynamicFunction(function_name); |
+ if (!cls_function.IsNull()) { |
+ functions->Add(&Function::ZoneHandle(cls_function.raw())); |
+ } |
+ } |
+ return functions; |
+} |
+ |
+ |
+ZoneGrowableArray<Function*>* ClassTable::GetOverridesOf( |
+ const Function& function) const { |
+ ASSERT(!function.IsNull()); |
+ ASSERT(function.IsDynamicFunction()); |
+ const Class& function_owner = Class::Handle(function.Owner()); |
+ const String& function_name = String::Handle(function.name()); |
+ ZoneGrowableArray<intptr_t>* cids = new ZoneGrowableArray<intptr_t>(); |
+ CollectSubclassIds(cids, function_owner); |
+ return GetNamedInstanceFunctionsOf(*cids, function_name); |
+} |
+ |
} // namespace dart |