Index: runtime/vm/object.cc |
=================================================================== |
--- runtime/vm/object.cc (revision 23883) |
+++ runtime/vm/object.cc (working copy) |
@@ -5991,6 +5991,137 @@ |
} |
+static RawString* MakeClassMetaName(const Class& cls) { |
+ String& cname = String::Handle(cls.Name()); |
+ return String::Concat(Symbols::At(), cname); |
+} |
+ |
+ |
+static RawString* MakeFieldMetaName(const Field& field) { |
+ const String& cname = |
+ String::Handle(MakeClassMetaName(Class::Handle(field.origin()))); |
+ String& fname = String::Handle(field.name()); |
+ fname = String::Concat(Symbols::At(), fname); |
+ return String::Concat(cname, fname); |
siva
2013/06/12 00:16:52
Maybe more efficient to use ConcatAll
String name
hausner
2013/06/12 01:10:05
I am not terribly concerned about speed here. Conc
|
+} |
+ |
+ |
+static RawString* MakeFunctionMetaName(const Function& func) { |
+ const String& cname = |
+ String::Handle(MakeClassMetaName(Class::Handle(func.origin()))); |
+ String& fname = String::Handle(func.name()); |
+ fname = String::Concat(Symbols::At(), fname); |
+ return String::Concat(cname, fname); |
siva
2013/06/12 00:16:52
Ditto here.
|
+} |
+ |
+ |
+void Library::AddClassMetadata(const Class& cls, intptr_t token_pos) const { |
+ String& metaname = String::Handle(MakeClassMetaName(cls)); |
+ metaname = Symbols::New(metaname); |
+ Field& meta_field = |
+ Field::Handle(Field::New(metaname, |
+ true, // is_static |
+ false, // is_final |
+ false, // is_const |
+ cls, |
+ token_pos)); |
+ meta_field.set_type(Type::Handle(Type::DynamicType())); |
+ meta_field.set_value(Array::empty_array()); |
+ GrowableObjectArray& metadata = |
+ GrowableObjectArray::Handle(this->metadata()); |
+ metadata.Add(meta_field, Heap::kOld); |
siva
2013/06/12 00:16:52
Seems like the above code could be abstracted into
hausner
2013/06/12 01:10:05
Done.
|
+} |
+ |
+ |
+void Library::AddFieldMetadata(const Field& field, |
+ intptr_t token_pos) const { |
+ String& metaname = String::Handle(MakeFieldMetaName(field)); |
+ metaname = Symbols::New(metaname); |
+ Field& meta_field = |
+ Field::Handle(Field::New(metaname, |
+ true, // is_static |
+ false, // is_final |
+ false, // is_const |
+ Class::Handle(field.origin()), |
+ token_pos)); |
+ meta_field.set_type(Type::Handle(Type::DynamicType())); |
+ meta_field.set_value(Array::empty_array()); |
+ GrowableObjectArray& metadata = GrowableObjectArray::Handle(this->metadata()); |
+ metadata.Add(meta_field, Heap::kOld); |
+} |
+ |
+ |
+void Library::AddFunctionMetadata(const Function& func, |
+ intptr_t token_pos) const { |
+ String& metaname = String::Handle(MakeFunctionMetaName(func)); |
+ metaname = Symbols::New(metaname); |
+ Field& meta_field = |
+ Field::Handle(Field::New(metaname, |
+ true, // is_static |
+ false, // is_final |
+ false, // is_const |
+ Class::Handle(func.origin()), |
+ token_pos)); |
+ meta_field.set_type(Type::Handle(Type::DynamicType())); |
+ meta_field.set_value(Object::empty_array()); |
+ GrowableObjectArray& metadata = GrowableObjectArray::Handle(this->metadata()); |
+ metadata.Add(meta_field, Heap::kOld); |
+} |
+ |
+ |
+RawString* Library::MakeMetadataName(const Object& obj) const { |
+ if (obj.IsClass()) { |
+ return MakeClassMetaName(Class::Cast(obj)); |
+ } else if (obj.IsField()) { |
+ return MakeFieldMetaName(Field::Cast(obj)); |
+ } else if (obj.IsFunction()) { |
+ return MakeFunctionMetaName(Function::Cast(obj)); |
+ } |
+ UNIMPLEMENTED(); |
+ return String::null(); |
+} |
+ |
+ |
+RawField* Library::GetMetadataField(const String& metaname) const { |
+ const GrowableObjectArray& metadata = |
+ GrowableObjectArray::Handle(this->metadata()); |
+ Field& entry = Field::Handle(); |
+ String& entryname = String::Handle(); |
+ intptr_t num_entries = metadata.Length(); |
+ for (intptr_t i = 0; i < num_entries; i++) { |
+ entry ^= metadata.At(i); |
+ entryname = entry.name(); |
+ if (entryname.Equals(metaname)) { |
+ return entry.raw(); |
+ } |
+ } |
+ return Field::null(); |
+} |
+ |
+ |
+RawObject* Library::GetMetadata(const Object& obj) const { |
+ if (!obj.IsClass() && !obj.IsField() && !obj.IsFunction()) { |
+ return Object::null(); |
+ } |
+ const String& metaname = String::Handle(MakeMetadataName(obj)); |
+ Field& field = Field::Handle(GetMetadataField(metaname)); |
+ if (field.IsNull()) { |
+ // There is no metadata for this object. |
+ return Object::empty_array().raw();; |
+ } |
+ Object& metadata = Object::Handle(); |
+ metadata = field.value(); |
+ if (field.value() == Object::empty_array().raw()) { |
+ metadata = Parser::ParseMetadata(Class::Handle(field.owner()), |
+ field.token_pos()); |
+ if (metadata.IsArray()) { |
siva
2013/06/12 00:16:52
ASSERT(Array::Cast(metadata).raw() != Object::empt
hausner
2013/06/12 01:10:05
Done.
|
+ field.set_value(Array::Cast(metadata)); |
+ } |
+ } |
+ return metadata.raw(); |
+} |
+ |
+ |
void Library::GrowDictionary(const Array& dict, intptr_t dict_size) const { |
// TODO(iposva): Avoid exponential growth. |
intptr_t new_dict_size = dict_size * 2; |
@@ -6529,6 +6660,7 @@ |
result.StorePointer(&result.raw_ptr()->url_, url.raw()); |
result.raw_ptr()->private_key_ = Scanner::AllocatePrivateKey(result); |
result.raw_ptr()->dictionary_ = Object::empty_array().raw(); |
+ result.raw_ptr()->metadata_ = GrowableObjectArray::New(4, Heap::kOld); |
siva
2013/06/12 00:16:52
result.StorePointer(&result.raw_ptr()->metadata_,
|
result.raw_ptr()->anonymous_classes_ = Object::empty_array().raw(); |
result.raw_ptr()->num_anonymous_ = 0; |
result.raw_ptr()->imports_ = Object::empty_array().raw(); |