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

Unified Diff: vm/object.cc

Issue 8342046: Add an imported into list for libraries so that it is possible to lookup (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: '' Created 9 years, 2 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: vm/object.cc
===================================================================
--- vm/object.cc (revision 557)
+++ vm/object.cc (working copy)
@@ -3406,22 +3406,46 @@
}
-ClassDictionaryIterator::ClassDictionaryIterator(const Library& library)
+DictionaryIterator::DictionaryIterator(const Library& library)
: array_(Array::Handle(library.dictionary())),
// Last element in array is a Smi.
size_(Array::Handle(library.dictionary()).Length() - 1),
next_ix_(0) {
+ MoveToNextObject();
+}
+
+
+RawObject* DictionaryIterator::GetNext() {
+ ASSERT(HasNext());
+ int ix = next_ix_++;
+ MoveToNextObject();
+ ASSERT(array_.At(ix) != Object::null());
+ return array_.At(ix);
+}
+
+
+void DictionaryIterator::MoveToNextObject() {
+ Object& obj = Object::Handle(array_.At(next_ix_));
+ while (obj.IsNull() && HasNext()) {
+ next_ix_++;
+ obj = array_.At(next_ix_);
+ }
+}
+
+
+ClassDictionaryIterator::ClassDictionaryIterator(const Library& library)
+ : DictionaryIterator(library) {
MoveToNextClass();
}
-RawClass* ClassDictionaryIterator::GetNext() {
+RawClass* ClassDictionaryIterator::GetNextClass() {
ASSERT(HasNext());
int ix = next_ix_++;
+ Object& obj = Object::Handle(array_.At(ix));
MoveToNextClass();
- ASSERT(array_.At(ix) != Object::null());
Class& cls = Class::Handle();
- cls ^= array_.At(ix);
+ cls ^= obj.raw();
return cls.raw();
}
@@ -3578,10 +3602,12 @@
RawObject* Library::LookupObject(const String& name) const {
+ // First check if the name is found in the local scope.
Object& obj = Object::Handle(LookupLocalObject(name));
if (!obj.IsNull()) {
return obj.raw();
}
+ // Now check if the name is found in the local scope of any imported libs.
Library& import = Library::Handle();
Array& imports = Array::Handle(this->imports());
for (intptr_t i = 0; i < num_imports(); i++) {
@@ -3595,6 +3621,106 @@
}
+RawObject* Library::LookupObjectInImporter(const String& name) const {
+ const Array& imported_into_libs = Array::Handle(this->imported_into());
+ Library& importer_lib = Library::Handle();
+ Object& obj = Object::Handle();
+ for (intptr_t i = 0; i < this->num_imported_into(); i++) {
+ importer_lib ^= imported_into_libs.At(i);
+ // Check if name is found in the top level scope of the importer.
+ ASSERT(importer_lib.raw() != raw());
+ // First check if name is found in the local scope of the library into
Ivan Posva 2011/10/20 08:46:04 Please factor this out as it is essentially Lookup
siva 2011/10/20 23:08:47 Done.
+ // which this is imported into.
+ obj = importer_lib.LookupLocalObject(name);
+ if (!obj.IsNull()) {
+ return obj.raw();
+ }
+ // Now check if name is found in the top level scope of libs imported
+ // by the importer.
+ const Array& imports = Array::Handle(importer_lib.imports());
+ Library& import_lib = Library::Handle();
+ for (intptr_t j = 0; j < importer_lib.num_imports(); j++) {
+ import_lib ^= imports.At(j);
+ if (import_lib.raw() == raw()) {
+ continue;
+ }
+ obj = import_lib.LookupLocalObject(name);
+ if (!obj.IsNull()) {
+ return obj.raw();
+ }
+ }
+ }
+ return Object::null();
+}
+
+
+RawString* Library::DuplicateDefineErrorString(const Object& obj) const {
+ Class& cls = Class::Handle();
+ Function& func = Function::Handle();
+ Field& field = Field::Handle();
+ String& errstr = String::Handle();
+ if (obj.IsClass()) {
+ cls ^= obj.raw();
+ errstr = cls.Name();
+ } else if (obj.IsFunction()) {
+ func ^= obj.raw();
+ cls ^= func.owner();
+ errstr = func.name();
+ } else if (obj.IsField()) {
+ field ^= obj.raw();
+ cls ^= field.owner();
+ errstr = field.name();
+ } else {
+ UNREACHABLE();
+ }
+ const Library& lib = Library::Handle(cls.library());
+ Array& array = Array::Handle(Array::New(5));
+ array.SetAt(0, errstr);
+ errstr = String::New(" is defined in libraries ");
+ array.SetAt(1, errstr);
+ errstr = url();
+ array.SetAt(2, errstr);
+ errstr = String::New(" and ");
+ array.SetAt(3, errstr);
+ errstr = lib.url();
+ array.SetAt(4, errstr);
+ errstr = String::ConcatAll(array);
+ return errstr.raw();
+}
+
+
+RawObject* Library::FindDuplicateDefinition() const {
+ DictionaryIterator it(*this);
+ Object& obj = Object::Handle();
+ Class& cls = Class::Handle();
+ Function& func = Function::Handle();
+ Field& field = Field::Handle();
+ String& entry_name = String::Handle();
+ while (it.HasNext()) {
+ obj = it.GetNext();
+ if (obj.IsNull()) {
Ivan Posva 2011/10/20 08:46:04 I don't think the iterator is ever handing out nul
siva 2011/10/20 23:08:47 True, I changed this to an assertion. On 2011/10/
+ continue;
+ } else if (obj.IsClass()) {
+ cls ^= obj.raw();
+ entry_name = cls.Name();
+ } else if (obj.IsFunction()) {
+ func ^= obj.raw();
+ entry_name = func.name();
+ } else if (obj.IsField()) {
+ field ^= obj.raw();
+ entry_name = field.name();
+ } else {
Ivan Posva 2011/10/20 08:46:04 Please add a comment explaining why you can skip l
siva 2011/10/20 23:08:47 Added comment stating that library prefixes in thi
+ continue;
+ }
+ obj = LookupObjectInImporter(entry_name);
+ if (!obj.IsNull()) {
+ return obj.raw();
+ }
+ }
+ return Object::null();
+}
+
+
RawClass* Library::LookupClass(const String& name) const {
Object& obj = Object::Handle(LookupObject(name));
if (!obj.IsNull() && obj.IsClass()) {
@@ -3654,9 +3780,24 @@
intptr_t index = num_imports();
imports.SetAt(index, library);
set_num_imports(index + 1);
+ library.AddImportedInto(*this);
}
+void Library::AddImportedInto(const Library& library) const {
+ Array& imported_into = Array::Handle(this->imported_into());
+ intptr_t capacity = imported_into.Length();
+ if (num_imported_into() == capacity) {
+ capacity = capacity + kImportedIntoCapacityIncrement;
+ imported_into = Array::Grow(imported_into, capacity);
+ StorePointer(&raw_ptr()->imported_into_, imported_into.raw());
+ }
+ intptr_t index = num_imported_into();
+ imported_into.SetAt(index, library);
+ set_num_imported_into(index + 1);
+}
+
+
void Library::InitClassDictionary() const {
// The last element of the dictionary specifies the number of in use slots.
// TODO(iposva): Find reasonable initial size.
@@ -3677,6 +3818,14 @@
}
+void Library::InitImportedIntoList() const {
+ const Array& imported_into =
+ Array::Handle(Array::New(kInitialImportedIntoCapacity, Heap::kOld));
+ StorePointer(&raw_ptr()->imported_into_, imported_into.raw());
+ raw_ptr()->num_imported_into_ = 0;
+}
+
+
RawLibrary* Library::New() {
const Class& library_class = Class::Handle(Object::library_class());
RawObject* raw = Object::Allocate(library_class,
@@ -3702,6 +3851,7 @@
result.raw_ptr()->loaded_ = false;
result.InitClassDictionary();
result.InitImportList();
+ result.InitImportedIntoList();
if (import_core_lib) {
Library& core_lib = Library::Handle(Library::CoreLibrary());
ASSERT(!core_lib.IsNull());
@@ -3753,6 +3903,25 @@
}
+RawString* Library::CheckForDuplicateDefinition() {
+ Library& lib = Library::Handle();
+ Isolate* isolate = Isolate::Current();
+ ASSERT(isolate != NULL);
+ ObjectStore* object_store = isolate->object_store();
+ ASSERT(object_store != NULL);
+ lib ^= object_store->registered_libraries();
+ Object& obj = Object::Handle();
+ while (!lib.IsNull()) {
+ obj = lib.FindDuplicateDefinition();
+ if (!obj.IsNull()) {
+ return lib.DuplicateDefineErrorString(obj);
+ }
+ lib ^= lib.next_registered();
+ }
+ return String::null();
+}
+
+
bool Library::IsKeyUsed(intptr_t key) {
intptr_t lib_key;
Library& lib = Library::Handle();
@@ -3846,7 +4015,7 @@
while (!lib.IsNull()) {
ClassDictionaryIterator it(lib);
while (it.HasNext()) {
- cls ^= it.GetNext();
+ cls ^= it.GetNextClass();
if (!cls.is_interface()) {
Compiler::CompileAllFunctions(cls);
}

Powered by Google App Engine
This is Rietveld 408576698