[vm] Cleanup lookups in the library import
Lookup in the library import can be very slow and it is not needed
most of the time. This change makes Library::Lookup{Class,Function,Field}[AllowPrivate]
lookups local in the library and cleans up related or unused code.
TEST=ci
Change-Id: If5a99bce7d712ce3a898395f74d4febac0311048
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/323221
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
committed by
Commit Queue
parent
899c88c997
commit
b9045af57b
@@ -517,7 +517,8 @@ ObjectPtr IsolateSpawnState::ResolveFunction() {
|
||||
// Check whether the root library defines a main function.
|
||||
const Library& lib =
|
||||
Library::Handle(zone, IG->object_store()->root_library());
|
||||
Function& func = Function::Handle(zone, lib.LookupLocalFunction(func_name));
|
||||
Function& func =
|
||||
Function::Handle(zone, lib.LookupFunctionAllowPrivate(func_name));
|
||||
if (func.IsNull()) {
|
||||
// Check whether main is reexported from the root library.
|
||||
const Object& obj = Object::Handle(zone, lib.LookupReExport(func_name));
|
||||
@@ -550,7 +551,7 @@ ObjectPtr IsolateSpawnState::ResolveFunction() {
|
||||
// Resolve the function.
|
||||
if (class_name() == nullptr) {
|
||||
const Function& func =
|
||||
Function::Handle(zone, lib.LookupLocalFunction(func_name));
|
||||
Function::Handle(zone, lib.LookupFunctionAllowPrivate(func_name));
|
||||
if (func.IsNull()) {
|
||||
const String& msg = String::Handle(
|
||||
zone, String::NewFormatted(
|
||||
@@ -562,7 +563,7 @@ ObjectPtr IsolateSpawnState::ResolveFunction() {
|
||||
}
|
||||
|
||||
const String& cls_name = String::Handle(zone, String::New(class_name()));
|
||||
const Class& cls = Class::Handle(zone, lib.LookupLocalClass(cls_name));
|
||||
const Class& cls = Class::Handle(zone, lib.LookupClass(cls_name));
|
||||
if (cls.IsNull()) {
|
||||
const String& msg = String::Handle(
|
||||
zone, String::NewFormatted(
|
||||
@@ -821,7 +822,7 @@ class SpawnIsolateTask : public ThreadPool::Task {
|
||||
const auto& lib = Library::Handle(zone, Library::IsolateLibrary());
|
||||
const auto& entry_name = String::Handle(zone, String::New("_startIsolate"));
|
||||
const auto& entry_point =
|
||||
Function::Handle(zone, lib.LookupLocalFunction(entry_name));
|
||||
Function::Handle(zone, lib.LookupFunctionAllowPrivate(entry_name));
|
||||
ASSERT(entry_point.IsFunction() && !entry_point.IsNull());
|
||||
const auto& result =
|
||||
Object::Handle(zone, DartEntry::InvokeFunction(entry_point, args));
|
||||
|
||||
@@ -761,7 +761,7 @@ void Precompiler::AddRoots() {
|
||||
}
|
||||
if (!main.IsNull()) {
|
||||
AddApiUse(main);
|
||||
if (lib.LookupLocalFunction(name) == Function::null()) {
|
||||
if (lib.LookupFunctionAllowPrivate(name) == Function::null()) {
|
||||
retain_root_library_caches_ = true;
|
||||
}
|
||||
AddRetainReason(main, RetainReasons::kMainFunction);
|
||||
|
||||
@@ -1526,7 +1526,7 @@ ISOLATE_UNIT_TEST_CASE(IL_Canonicalize_FinalFieldForwarding) {
|
||||
const auto& lib = Library::Handle(LoadTestScript(script_chars));
|
||||
|
||||
const auto& test_cls = Class::ZoneHandle(
|
||||
lib.LookupLocalClass(String::Handle(Symbols::New(thread, "TestClass"))));
|
||||
lib.LookupClass(String::Handle(Symbols::New(thread, "TestClass"))));
|
||||
const auto& err = Error::Handle(test_cls.EnsureIsFinalized(thread));
|
||||
EXPECT(err.IsNull());
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ ISOLATE_UNIT_TEST_CASE(Inliner_PolyInliningRedefinition) {
|
||||
/*insert_before=*/kMoveGlob));
|
||||
|
||||
const Class& cls = Class::Handle(
|
||||
root_library.LookupLocalClass(String::Handle(Symbols::New(thread, "B"))));
|
||||
root_library.LookupClass(String::Handle(Symbols::New(thread, "B"))));
|
||||
|
||||
Definition* cid_B = flow_graph->GetConstant(Smi::Handle(Smi::New(cls.id())));
|
||||
Instruction* current = prelude;
|
||||
|
||||
@@ -226,7 +226,7 @@ static void TestAliasingViaRedefinition(
|
||||
Library::Handle(LoadTestScript(script_chars, NoopNativeLookup));
|
||||
|
||||
const Class& cls = Class::ZoneHandle(
|
||||
lib.LookupLocalClass(String::Handle(Symbols::New(thread, "K"))));
|
||||
lib.LookupClass(String::Handle(Symbols::New(thread, "K"))));
|
||||
const Error& err = Error::Handle(cls.EnsureIsFinalized(thread));
|
||||
EXPECT(err.IsNull());
|
||||
|
||||
@@ -391,7 +391,7 @@ static void TestAliasingViaStore(
|
||||
Library::Handle(LoadTestScript(script_chars, NoopNativeLookup));
|
||||
|
||||
const Class& cls = Class::ZoneHandle(
|
||||
lib.LookupLocalClass(String::Handle(Symbols::New(thread, "K"))));
|
||||
lib.LookupClass(String::Handle(Symbols::New(thread, "K"))));
|
||||
const Error& err = Error::Handle(cls.EnsureIsFinalized(thread));
|
||||
EXPECT(err.IsNull());
|
||||
|
||||
@@ -563,7 +563,7 @@ ISOLATE_UNIT_TEST_CASE(LoadOptimizer_AliasingViaTypedDataAndUntaggedTypedData) {
|
||||
FlowGraphBuilderHelper H;
|
||||
|
||||
const auto& lib = Library::Handle(Library::TypedDataLibrary());
|
||||
const Class& cls = Class::Handle(lib.LookupLocalClass(Symbols::Uint32List()));
|
||||
const Class& cls = Class::Handle(lib.LookupClass(Symbols::Uint32List()));
|
||||
const Error& err = Error::Handle(cls.EnsureIsFinalized(thread));
|
||||
EXPECT(err.IsNull());
|
||||
|
||||
@@ -681,7 +681,7 @@ ISOLATE_UNIT_TEST_CASE(LoadOptimizer_TypedArrayViewAliasing) {
|
||||
Library::Handle(LoadTestScript(script_chars, NoopNativeLookup));
|
||||
|
||||
const Class& view_cls = Class::ZoneHandle(
|
||||
lib.LookupLocalClass(String::Handle(Symbols::New(thread, "View"))));
|
||||
lib.LookupClass(String::Handle(Symbols::New(thread, "View"))));
|
||||
const Error& err = Error::Handle(view_cls.EnsureIsFinalized(thread));
|
||||
EXPECT(err.IsNull());
|
||||
|
||||
@@ -1501,7 +1501,7 @@ ISOLATE_UNIT_TEST_CASE(CSE_Redefinitions) {
|
||||
Library::Handle(LoadTestScript(script_chars, NoopNativeLookup));
|
||||
|
||||
const Class& cls = Class::ZoneHandle(
|
||||
lib.LookupLocalClass(String::Handle(Symbols::New(thread, "K"))));
|
||||
lib.LookupClass(String::Handle(Symbols::New(thread, "K"))));
|
||||
const Error& err = Error::Handle(cls.EnsureIsFinalized(thread));
|
||||
EXPECT(err.IsNull());
|
||||
|
||||
|
||||
@@ -490,8 +490,9 @@ Fragment FlowGraphBuilder::ThrowLateInitializationError(
|
||||
TokenPosition position,
|
||||
const char* throw_method_name,
|
||||
const String& name) {
|
||||
const auto& dart_internal = Library::Handle(Z, Library::InternalLibrary());
|
||||
const Class& klass =
|
||||
Class::ZoneHandle(Z, Library::LookupCoreClass(Symbols::LateError()));
|
||||
Class::ZoneHandle(Z, dart_internal.LookupClass(Symbols::LateError()));
|
||||
ASSERT(!klass.IsNull());
|
||||
|
||||
const auto& error = klass.EnsureIsFinalized(thread_);
|
||||
|
||||
@@ -320,7 +320,7 @@ namespace dart {
|
||||
V(::, reachabilityFence, ReachabilityFence, 0x73009f9f) \
|
||||
V(_Utf8Decoder, _scan, Utf8DecoderScan, 0xb98ea6c2) \
|
||||
V(_FutureListener, handleValue, FutureListenerHandleValue, 0xec1745d2) \
|
||||
V(::, has63BitSmis, Has63BitSmis, 0xf60ccb11) \
|
||||
V(::, get:has63BitSmis, Has63BitSmis, 0xf60ccb11) \
|
||||
V(::, get:extensionStreamHasListener, ExtensionStreamHasListener, 0xfaa5db24)\
|
||||
V(_Smi, get:hashCode, Smi_hashCode, 0x75d240f2) \
|
||||
V(_Mint, get:hashCode, Mint_hashCode, 0x75d240f2) \
|
||||
|
||||
@@ -5922,8 +5922,9 @@ DART_EXPORT Dart_Handle Dart_FinalizeLoading(bool complete_futures) {
|
||||
if (FLAG_enable_mirrors) {
|
||||
// Notify mirrors that MirrorSystem.libraries needs to be recomputed.
|
||||
const Library& libmirrors = Library::Handle(Z, Library::MirrorsLibrary());
|
||||
const Field& dirty_bit = Field::Handle(
|
||||
Z, libmirrors.LookupLocalField(String::Handle(String::New("_dirty"))));
|
||||
const Field& dirty_bit =
|
||||
Field::Handle(Z, libmirrors.LookupFieldAllowPrivate(
|
||||
String::Handle(String::New("_dirty"))));
|
||||
ASSERT(!dirty_bit.IsNull() && dirty_bit.is_static());
|
||||
dirty_bit.SetStaticValue(Bool::True());
|
||||
}
|
||||
|
||||
@@ -3163,7 +3163,7 @@ ErrorPtr Isolate::InvokePendingServiceExtensionCalls() {
|
||||
const Library& developer_lib = Library::Handle(Library::DeveloperLibrary());
|
||||
ASSERT(!developer_lib.IsNull());
|
||||
const Function& run_extension = Function::Handle(
|
||||
developer_lib.LookupLocalFunction(Symbols::_runExtension()));
|
||||
developer_lib.LookupFunctionAllowPrivate(Symbols::_runExtension()));
|
||||
ASSERT(!run_extension.IsNull());
|
||||
|
||||
const Array& arguments =
|
||||
|
||||
@@ -2120,7 +2120,7 @@ ClassPtr KernelLoader::LookupClass(const Library& library, NameIndex klass) {
|
||||
|
||||
ASSERT(!library.IsNull());
|
||||
const String& name = H.DartClassName(klass);
|
||||
Class& handle = Class::Handle(Z, library.LookupLocalClass(name));
|
||||
Class& handle = Class::Handle(Z, library.LookupClass(name));
|
||||
bool register_class = true;
|
||||
if (handle.IsNull()) {
|
||||
// We do not register expression evaluation classes with the VM:
|
||||
|
||||
+11
-180
@@ -13645,36 +13645,6 @@ static bool ShouldBePrivate(const String& name) {
|
||||
name.CharAt(1) == 'e' && name.CharAt(2) == 't' &&
|
||||
name.CharAt(3) == ':'));
|
||||
}
|
||||
|
||||
ObjectPtr Library::ResolveName(const String& name) const {
|
||||
Object& obj = Object::Handle();
|
||||
if (FLAG_use_lib_cache && LookupResolvedNamesCache(name, &obj)) {
|
||||
return obj.ptr();
|
||||
}
|
||||
EnsureTopLevelClassIsFinalized();
|
||||
obj = LookupLocalObject(name);
|
||||
if (!obj.IsNull()) {
|
||||
// Names that are in this library's dictionary and are unmangled
|
||||
// are not cached. This reduces the size of the cache.
|
||||
return obj.ptr();
|
||||
}
|
||||
String& accessor_name = String::Handle(Field::LookupGetterSymbol(name));
|
||||
if (!accessor_name.IsNull()) {
|
||||
obj = LookupLocalObject(accessor_name);
|
||||
}
|
||||
if (obj.IsNull()) {
|
||||
accessor_name = Field::LookupSetterSymbol(name);
|
||||
if (!accessor_name.IsNull()) {
|
||||
obj = LookupLocalObject(accessor_name);
|
||||
}
|
||||
if (obj.IsNull() && !ShouldBePrivate(name)) {
|
||||
obj = LookupImportedObject(name);
|
||||
}
|
||||
}
|
||||
AddToResolvedNamesCache(name, obj);
|
||||
return obj.ptr();
|
||||
}
|
||||
|
||||
class StringEqualsTraits {
|
||||
public:
|
||||
static const char* Name() { return "StringEqualsTraits"; }
|
||||
@@ -14103,15 +14073,6 @@ ObjectPtr Library::LookupLocalOrReExportObject(const String& name) const {
|
||||
}
|
||||
|
||||
FieldPtr Library::LookupFieldAllowPrivate(const String& name) const {
|
||||
EnsureTopLevelClassIsFinalized();
|
||||
Object& obj = Object::Handle(LookupObjectAllowPrivate(name));
|
||||
if (obj.IsField()) {
|
||||
return Field::Cast(obj).ptr();
|
||||
}
|
||||
return Field::null();
|
||||
}
|
||||
|
||||
FieldPtr Library::LookupLocalField(const String& name) const {
|
||||
EnsureTopLevelClassIsFinalized();
|
||||
Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name));
|
||||
if (obj.IsField()) {
|
||||
@@ -14121,15 +14082,6 @@ FieldPtr Library::LookupLocalField(const String& name) const {
|
||||
}
|
||||
|
||||
FunctionPtr Library::LookupFunctionAllowPrivate(const String& name) const {
|
||||
EnsureTopLevelClassIsFinalized();
|
||||
Object& obj = Object::Handle(LookupObjectAllowPrivate(name));
|
||||
if (obj.IsFunction()) {
|
||||
return Function::Cast(obj).ptr();
|
||||
}
|
||||
return Function::null();
|
||||
}
|
||||
|
||||
FunctionPtr Library::LookupLocalFunction(const String& name) const {
|
||||
EnsureTopLevelClassIsFinalized();
|
||||
Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name));
|
||||
if (obj.IsFunction()) {
|
||||
@@ -14150,95 +14102,7 @@ ObjectPtr Library::LookupLocalObjectAllowPrivate(const String& name) const {
|
||||
return obj.ptr();
|
||||
}
|
||||
|
||||
ObjectPtr Library::LookupObjectAllowPrivate(const String& name) const {
|
||||
// First check if name is found in the local scope of the library.
|
||||
Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name));
|
||||
if (!obj.IsNull()) {
|
||||
return obj.ptr();
|
||||
}
|
||||
|
||||
// Do not look up private names in imported libraries.
|
||||
if (ShouldBePrivate(name)) {
|
||||
return Object::null();
|
||||
}
|
||||
|
||||
// Now check if name is found in any imported libs.
|
||||
return LookupImportedObject(name);
|
||||
}
|
||||
|
||||
ObjectPtr Library::LookupImportedObject(const String& name) const {
|
||||
Object& obj = Object::Handle();
|
||||
Namespace& import = Namespace::Handle();
|
||||
Library& import_lib = Library::Handle();
|
||||
String& import_lib_url = String::Handle();
|
||||
String& first_import_lib_url = String::Handle();
|
||||
Object& found_obj = Object::Handle();
|
||||
String& found_obj_name = String::Handle();
|
||||
ASSERT(!ShouldBePrivate(name));
|
||||
for (intptr_t i = 0; i < num_imports(); i++) {
|
||||
import = ImportAt(i);
|
||||
obj = import.Lookup(name);
|
||||
if (!obj.IsNull()) {
|
||||
import_lib = import.target();
|
||||
import_lib_url = import_lib.url();
|
||||
if (found_obj.ptr() != obj.ptr()) {
|
||||
if (first_import_lib_url.IsNull() ||
|
||||
first_import_lib_url.StartsWith(Symbols::DartScheme())) {
|
||||
// This is the first object we found, or the
|
||||
// previously found object is exported from a Dart
|
||||
// system library. The newly found object hides the one
|
||||
// from the Dart library.
|
||||
first_import_lib_url = import_lib.url();
|
||||
found_obj = obj.ptr();
|
||||
found_obj_name = obj.DictionaryName();
|
||||
} else if (import_lib_url.StartsWith(Symbols::DartScheme())) {
|
||||
// The newly found object is exported from a Dart system
|
||||
// library. It is hidden by the previously found object.
|
||||
// We continue to search.
|
||||
} else if (Field::IsSetterName(found_obj_name) &&
|
||||
!Field::IsSetterName(name)) {
|
||||
// We are looking for an unmangled name or a getter, but
|
||||
// the first object we found is a setter. Replace the first
|
||||
// object with the one we just found.
|
||||
first_import_lib_url = import_lib.url();
|
||||
found_obj = obj.ptr();
|
||||
found_obj_name = found_obj.DictionaryName();
|
||||
} else {
|
||||
// We found two different objects with the same name.
|
||||
// Note that we need to compare the names again because
|
||||
// looking up an unmangled name can return a getter or a
|
||||
// setter. A getter name is the same as the unmangled name,
|
||||
// but a setter name is different from an unmangled name or a
|
||||
// getter name.
|
||||
if (Field::IsGetterName(found_obj_name)) {
|
||||
found_obj_name = Field::NameFromGetter(found_obj_name);
|
||||
}
|
||||
String& second_obj_name = String::Handle(obj.DictionaryName());
|
||||
if (Field::IsGetterName(second_obj_name)) {
|
||||
second_obj_name = Field::NameFromGetter(second_obj_name);
|
||||
}
|
||||
if (found_obj_name.Equals(second_obj_name)) {
|
||||
return Object::null();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return found_obj.ptr();
|
||||
}
|
||||
|
||||
ClassPtr Library::LookupClass(const String& name) const {
|
||||
Object& obj = Object::Handle(LookupLocalObject(name));
|
||||
if (obj.IsNull() && !ShouldBePrivate(name)) {
|
||||
obj = LookupImportedObject(name);
|
||||
}
|
||||
if (obj.IsClass()) {
|
||||
return Class::Cast(obj).ptr();
|
||||
}
|
||||
return Class::null();
|
||||
}
|
||||
|
||||
ClassPtr Library::LookupLocalClass(const String& name) const {
|
||||
Object& obj = Object::Handle(LookupLocalObject(name));
|
||||
if (obj.IsClass()) {
|
||||
return Class::Cast(obj).ptr();
|
||||
@@ -14247,41 +14111,9 @@ ClassPtr Library::LookupLocalClass(const String& name) const {
|
||||
}
|
||||
|
||||
ClassPtr Library::LookupClassAllowPrivate(const String& name) const {
|
||||
// See if the class is available in this library or in the top level
|
||||
// scope of any imported library.
|
||||
Zone* zone = Thread::Current()->zone();
|
||||
const Class& cls = Class::Handle(zone, LookupClass(name));
|
||||
if (!cls.IsNull()) {
|
||||
return cls.ptr();
|
||||
}
|
||||
|
||||
// Now try to lookup the class using its private name, but only in
|
||||
// this library (not in imported libraries).
|
||||
if (ShouldBePrivate(name)) {
|
||||
String& private_name = String::Handle(zone, PrivateName(name));
|
||||
const Object& obj = Object::Handle(LookupLocalObject(private_name));
|
||||
if (obj.IsClass()) {
|
||||
return Class::Cast(obj).ptr();
|
||||
}
|
||||
}
|
||||
return Class::null();
|
||||
}
|
||||
|
||||
// Mixin applications can have multiple private keys from different libraries.
|
||||
ClassPtr Library::SlowLookupClassAllowMultiPartPrivate(
|
||||
const String& name) const {
|
||||
Array& dict = Array::Handle(dictionary());
|
||||
Object& entry = Object::Handle();
|
||||
String& cls_name = String::Handle();
|
||||
for (intptr_t i = 0; i < dict.Length(); i++) {
|
||||
entry = dict.At(i);
|
||||
if (entry.IsClass()) {
|
||||
cls_name = Class::Cast(entry).Name();
|
||||
// Warning: comparison is not symmetric.
|
||||
if (String::EqualsIgnoringPrivateKey(cls_name, name)) {
|
||||
return Class::Cast(entry).ptr();
|
||||
}
|
||||
}
|
||||
Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name));
|
||||
if (obj.IsClass()) {
|
||||
return Class::Cast(obj).ptr();
|
||||
}
|
||||
return Class::null();
|
||||
}
|
||||
@@ -15514,19 +15346,18 @@ FunctionPtr Library::GetFunction(const GrowableArray<Library*>& libs,
|
||||
for (intptr_t l = 0; l < libs.length(); l++) {
|
||||
const Library& lib = *libs[l];
|
||||
if (strcmp(class_name, "::") == 0) {
|
||||
func_str = Symbols::New(thread, function_name);
|
||||
func = lib.LookupFunctionAllowPrivate(func_str);
|
||||
cls = lib.toplevel_class();
|
||||
} else {
|
||||
class_str = String::New(class_name);
|
||||
cls = lib.LookupClassAllowPrivate(class_str);
|
||||
if (!cls.IsNull()) {
|
||||
if (cls.EnsureIsFinalized(thread) == Error::null()) {
|
||||
func_str = String::New(function_name);
|
||||
if (function_name[0] == '.') {
|
||||
func_str = String::Concat(class_str, func_str);
|
||||
}
|
||||
func = cls.LookupFunctionAllowPrivate(func_str);
|
||||
}
|
||||
if (!cls.IsNull()) {
|
||||
if (cls.EnsureIsFinalized(thread) == Error::null()) {
|
||||
func_str = String::New(function_name);
|
||||
if (function_name[0] == '.') {
|
||||
func_str = String::Concat(class_str, func_str);
|
||||
}
|
||||
func = cls.LookupFunctionAllowPrivate(func_str);
|
||||
}
|
||||
}
|
||||
if (!func.IsNull()) {
|
||||
|
||||
+4
-19
@@ -5112,18 +5112,14 @@ class Library : public Object {
|
||||
ObjectPtr LookupReExport(
|
||||
const String& name,
|
||||
ZoneGrowableArray<intptr_t>* visited = nullptr) const;
|
||||
ObjectPtr LookupObjectAllowPrivate(const String& name) const;
|
||||
ObjectPtr LookupLocalOrReExportObject(const String& name) const;
|
||||
ObjectPtr LookupImportedObject(const String& name) const;
|
||||
LibraryPrefixPtr LookupLocalLibraryPrefix(const String& name) const;
|
||||
|
||||
// These lookups are local within the library.
|
||||
ClassPtr LookupClass(const String& name) const;
|
||||
ClassPtr LookupClassAllowPrivate(const String& name) const;
|
||||
ClassPtr SlowLookupClassAllowMultiPartPrivate(const String& name) const;
|
||||
ClassPtr LookupLocalClass(const String& name) const;
|
||||
FieldPtr LookupFieldAllowPrivate(const String& name) const;
|
||||
FieldPtr LookupLocalField(const String& name) const;
|
||||
FunctionPtr LookupFunctionAllowPrivate(const String& name) const;
|
||||
FunctionPtr LookupLocalFunction(const String& name) const;
|
||||
LibraryPrefixPtr LookupLocalLibraryPrefix(const String& name) const;
|
||||
|
||||
// Look up a Script based on a url. If 'useResolvedUri' is not provided or is
|
||||
// false, 'url' should have a 'dart:' scheme for Dart core libraries,
|
||||
@@ -5134,17 +5130,6 @@ class Library : public Object {
|
||||
ScriptPtr LookupScript(const String& url, bool useResolvedUri = false) const;
|
||||
ArrayPtr LoadedScripts() const;
|
||||
|
||||
// Resolve name in the scope of this library. First check the cache
|
||||
// of already resolved names for this library. Then look in the
|
||||
// local dictionary for the unmangled name N, the getter name get:N
|
||||
// and setter name set:N.
|
||||
// If the local dictionary contains no entry for these names,
|
||||
// look in the scopes of all libraries that are imported
|
||||
// without a library prefix.
|
||||
ObjectPtr ResolveName(const String& name) const;
|
||||
|
||||
void AddAnonymousClass(const Class& cls) const;
|
||||
|
||||
void AddExport(const Namespace& ns) const;
|
||||
|
||||
void AddMetadata(const Object& declaration, intptr_t kernel_offset) const;
|
||||
@@ -5423,8 +5408,8 @@ class Library : public Object {
|
||||
void RehashDictionary(const Array& old_dict, intptr_t new_dict_size) const;
|
||||
static LibraryPtr NewLibraryHelper(const String& url, bool import_core_lib);
|
||||
ObjectPtr LookupEntry(const String& name, intptr_t* index) const;
|
||||
ObjectPtr LookupLocalObjectAllowPrivate(const String& name) const;
|
||||
ObjectPtr LookupLocalObject(const String& name) const;
|
||||
ObjectPtr LookupLocalObjectAllowPrivate(const String& name) const;
|
||||
|
||||
void AllocatePrivateKey() const;
|
||||
|
||||
|
||||
@@ -5666,18 +5666,20 @@ TEST_CASE(Metadata) {
|
||||
res = lib.GetMetadata(func);
|
||||
PrintMetadata("A.aFunc", res);
|
||||
|
||||
func = lib.LookupLocalFunction(String::Handle(Symbols::New(thread, "main")));
|
||||
func = lib.LookupFunctionAllowPrivate(
|
||||
String::Handle(Symbols::New(thread, "main")));
|
||||
EXPECT(!func.IsNull());
|
||||
res = lib.GetMetadata(func);
|
||||
PrintMetadata("main", res);
|
||||
|
||||
func = lib.LookupLocalFunction(
|
||||
func = lib.LookupFunctionAllowPrivate(
|
||||
String::Handle(Symbols::New(thread, "get:tlGetter")));
|
||||
EXPECT(!func.IsNull());
|
||||
res = lib.GetMetadata(func);
|
||||
PrintMetadata("tlGetter", res);
|
||||
|
||||
field = lib.LookupLocalField(String::Handle(Symbols::New(thread, "gVar")));
|
||||
field =
|
||||
lib.LookupFieldAllowPrivate(String::Handle(Symbols::New(thread, "gVar")));
|
||||
EXPECT(!field.IsNull());
|
||||
res = lib.GetMetadata(field);
|
||||
PrintMetadata("gVar", res);
|
||||
|
||||
@@ -214,83 +214,4 @@ FunctionPtr Resolver::ResolveDynamicAnyArgsAllowPrivate(
|
||||
std::mem_fn(&Class::LookupDynamicFunctionAllowPrivate));
|
||||
}
|
||||
|
||||
FunctionPtr Resolver::ResolveStatic(const Library& library,
|
||||
const String& class_name,
|
||||
const String& function_name,
|
||||
intptr_t type_args_len,
|
||||
intptr_t num_arguments,
|
||||
const Array& argument_names) {
|
||||
ASSERT(!library.IsNull());
|
||||
Function& function = Function::Handle();
|
||||
if (class_name.IsNull() || (class_name.Length() == 0)) {
|
||||
// Check if we are referring to a top level function.
|
||||
const Object& object = Object::Handle(library.ResolveName(function_name));
|
||||
if (!object.IsNull() && object.IsFunction()) {
|
||||
function ^= object.ptr();
|
||||
if (!function.AreValidArguments(type_args_len, num_arguments,
|
||||
argument_names, nullptr)) {
|
||||
if (FLAG_trace_resolving) {
|
||||
String& error_message = String::Handle();
|
||||
// Obtain more detailed error message.
|
||||
function.AreValidArguments(type_args_len, num_arguments,
|
||||
argument_names, &error_message);
|
||||
THR_Print("ResolveStatic error '%s': %s.\n",
|
||||
function_name.ToCString(), error_message.ToCString());
|
||||
}
|
||||
function = Function::null();
|
||||
}
|
||||
} else {
|
||||
if (FLAG_trace_resolving) {
|
||||
THR_Print("ResolveStatic error: function '%s' not found.\n",
|
||||
function_name.ToCString());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Lookup class_name in the library's class dictionary to get at
|
||||
// the dart class object. If class_name is not found in the dictionary
|
||||
// ResolveStatic will return a nullptr function object.
|
||||
const Class& cls = Class::Handle(library.LookupClass(class_name));
|
||||
if (!cls.IsNull()) {
|
||||
function = ResolveStatic(cls, function_name, type_args_len, num_arguments,
|
||||
argument_names);
|
||||
}
|
||||
if (FLAG_trace_resolving && function.IsNull()) {
|
||||
THR_Print("ResolveStatic error: function '%s.%s' not found.\n",
|
||||
class_name.ToCString(), function_name.ToCString());
|
||||
}
|
||||
}
|
||||
return function.ptr();
|
||||
}
|
||||
|
||||
FunctionPtr Resolver::ResolveStatic(const Class& cls,
|
||||
const String& function_name,
|
||||
intptr_t type_args_len,
|
||||
intptr_t num_arguments,
|
||||
const Array& argument_names) {
|
||||
ASSERT(!cls.IsNull());
|
||||
if (FLAG_trace_resolving) {
|
||||
THR_Print("ResolveStatic '%s'\n", function_name.ToCString());
|
||||
}
|
||||
const Function& function =
|
||||
Function::Handle(cls.LookupStaticFunction(function_name));
|
||||
if (function.IsNull() ||
|
||||
!function.AreValidArguments(type_args_len, num_arguments, argument_names,
|
||||
nullptr)) {
|
||||
// Return a null function to signal to the upper levels to throw a
|
||||
// resolution error or maybe throw the error right here.
|
||||
if (FLAG_trace_resolving) {
|
||||
String& error_message = String::Handle(String::New("function not found"));
|
||||
if (!function.IsNull()) {
|
||||
// Obtain more detailed error message.
|
||||
function.AreValidArguments(type_args_len, num_arguments, argument_names,
|
||||
&error_message);
|
||||
}
|
||||
THR_Print("ResolveStatic error '%s': %s.\n", function_name.ToCString(),
|
||||
error_message.ToCString());
|
||||
}
|
||||
return Function::null();
|
||||
}
|
||||
return function.ptr();
|
||||
}
|
||||
|
||||
} // namespace dart
|
||||
|
||||
@@ -60,27 +60,6 @@ class Resolver : public AllStatic {
|
||||
static FunctionPtr ResolveFunction(Zone* zone,
|
||||
const Class& receiver_class,
|
||||
const String& function_name);
|
||||
|
||||
// Resolve specified dart static function. If library.IsNull, use
|
||||
// either application library or core library if no application library
|
||||
// exists. Passing negative num_arguments means that the function
|
||||
// will be resolved by name only.
|
||||
// Otherwise null is returned if the number or names of arguments are not
|
||||
// valid for the resolved function.
|
||||
static FunctionPtr ResolveStatic(const Library& library,
|
||||
const String& cls_name,
|
||||
const String& function_name,
|
||||
intptr_t type_args_len,
|
||||
intptr_t num_arguments,
|
||||
const Array& argument_names);
|
||||
|
||||
// Resolve specified dart static function with specified arity. Only resolves
|
||||
// public functions.
|
||||
static FunctionPtr ResolveStatic(const Class& cls,
|
||||
const String& function_name,
|
||||
intptr_t type_args_len,
|
||||
intptr_t num_arguments,
|
||||
const Array& argument_names);
|
||||
};
|
||||
|
||||
} // namespace dart
|
||||
|
||||
@@ -330,9 +330,11 @@ bool SourceReport::ShouldCoverageSkipCallSite(const ICData* ic_data) {
|
||||
// shouldn't count against the coverage total.
|
||||
// See https://github.com/dart-lang/coverage/issues/341
|
||||
if (late_error_class_id_ == ClassId::kIllegalCid) {
|
||||
const Class& lateErrorClass =
|
||||
Class::Handle(Library::LookupCoreClass(Symbols::LateError()));
|
||||
late_error_class_id_ = lateErrorClass.id();
|
||||
const auto& dart_internal = Library::Handle(Library::InternalLibrary());
|
||||
const auto& late_error_class =
|
||||
Class::Handle(dart_internal.LookupClass(Symbols::LateError()));
|
||||
ASSERT(!late_error_class.IsNull());
|
||||
late_error_class_id_ = late_error_class.id();
|
||||
}
|
||||
Class& cls = Class::Handle(func.Owner());
|
||||
if (late_error_class_id_ == cls.id()) {
|
||||
|
||||
@@ -452,7 +452,7 @@ ISOLATE_UNIT_TEST_CASE(SourceReport_Coverage_RestrictedRange) {
|
||||
const Script& script =
|
||||
Script::Handle(lib.LookupScript(String::Handle(String::New("test-lib"))));
|
||||
const Function& helper = Function::Handle(
|
||||
lib.LookupLocalFunction(String::Handle(String::New("helper0"))));
|
||||
lib.LookupFunctionAllowPrivate(String::Handle(String::New("helper0"))));
|
||||
|
||||
SourceReport report(SourceReport::kCoverage);
|
||||
JSONStream js;
|
||||
@@ -645,7 +645,7 @@ ISOLATE_UNIT_TEST_CASE(SourceReport_CallSites_PolymorphicCall) {
|
||||
const Script& script =
|
||||
Script::Handle(lib.LookupScript(String::Handle(String::New("test-lib"))));
|
||||
const Function& helper = Function::Handle(
|
||||
lib.LookupLocalFunction(String::Handle(String::New("helper"))));
|
||||
lib.LookupFunctionAllowPrivate(String::Handle(String::New("helper"))));
|
||||
|
||||
SourceReport report(SourceReport::kCallSites);
|
||||
JSONStream js;
|
||||
|
||||
Reference in New Issue
Block a user