[vm/resolution] Wrap few Class::Lookup.*FunctionUnsafe() methods in Resolver::Resolve.*() methods.

Add "Unsafe" suffix to those Class::Lookup* methods to indicate they will need program
structure protection locking.

This allows to localize program structure protection locking inside of those Resolver methods.

Bug: https://github.com/dart-lang/sdk/issues/36097
Change-Id: Ie5b0a190f6d3256448f2e528fa8ee52421e1639a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/167960
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This commit is contained in:
Alexander Aprelev 2020-10-16 19:22:52 +00:00 committed by commit-bot@chromium.org
parent 6f6a507dee
commit a7c612e187
17 changed files with 135 additions and 85 deletions

View file

@ -14,6 +14,7 @@
#include "vm/object_store.h"
#include "vm/parser.h"
#include "vm/port.h"
#include "vm/resolver.h"
#include "vm/symbols.h"
namespace dart {
@ -1442,8 +1443,8 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 0, 5) {
external_constructor_name = internal_constructor_name.raw();
}
Function& lookup_constructor =
Function::Handle(klass.LookupFunction(internal_constructor_name));
Function& lookup_constructor = Function::Handle(
Resolver::ResolveFunction(zone, klass, internal_constructor_name));
if (lookup_constructor.IsNull() ||
(lookup_constructor.kind() != FunctionLayout::kConstructor) ||

View file

@ -149,7 +149,7 @@ bool CHA::HasOverride(const Class& cls,
continue;
}
if (direct_subclass.LookupDynamicFunction(function_name) !=
if (direct_subclass.LookupDynamicFunctionUnsafe(function_name) !=
Function::null()) {
return true;
}

View file

@ -6,11 +6,14 @@
#include "platform/assert.h"
#include "vm/class_finalizer.h"
#include "vm/globals.h"
#include "vm/resolver.h"
#include "vm/symbols.h"
#include "vm/unit_test.h"
namespace dart {
#define Z (thread->zone())
TEST_CASE(ClassHierarchyAnalysis) {
const char* kScriptChars =
"class A {"
@ -57,24 +60,24 @@ TEST_CASE(ClassHierarchyAnalysis) {
const String& function_foo_name = String::Handle(String::New("foo"));
const String& function_bar_name = String::Handle(String::New("bar"));
const Function& class_a_foo =
Function::Handle(class_a.LookupDynamicFunction(function_foo_name));
const Function& class_a_foo = Function::Handle(
Resolver::ResolveDynamicFunction(Z, class_a, function_foo_name));
EXPECT(!class_a_foo.IsNull());
const Function& class_a_bar =
Function::Handle(class_a.LookupDynamicFunction(function_bar_name));
const Function& class_a_bar = Function::Handle(
Resolver::ResolveDynamicFunction(Z, class_a, function_bar_name));
EXPECT(!class_a_bar.IsNull());
const Function& class_c_foo =
Function::Handle(class_c.LookupDynamicFunction(function_foo_name));
const Function& class_c_foo = Function::Handle(
Resolver::ResolveDynamicFunction(Z, class_c, function_foo_name));
EXPECT(!class_c_foo.IsNull());
const Function& class_d_foo =
Function::Handle(class_d.LookupDynamicFunction(function_foo_name));
const Function& class_d_foo = Function::Handle(
Resolver::ResolveDynamicFunction(Z, class_d, function_foo_name));
EXPECT(!class_d_foo.IsNull());
const Function& class_d_bar =
Function::Handle(class_d.LookupDynamicFunction(function_bar_name));
const Function& class_d_bar = Function::Handle(
Resolver::ResolveDynamicFunction(Z, class_d, function_bar_name));
EXPECT(!class_d_bar.IsNull());
CHA cha(thread);

View file

@ -11,6 +11,7 @@
#include "vm/compiler/runtime_api.h"
#include "vm/growable_array.h"
#include "vm/object_store.h"
#include "vm/resolver.h"
namespace dart {
namespace kernel {
@ -1108,7 +1109,7 @@ Fragment BaseFlowGraphBuilder::BuildEntryPointsIntrospection() {
const auto& func_name = String::Handle(Z, parent.name());
const auto& owner = Class::Handle(Z, parent.Owner());
if (owner.EnsureIsFinalized(thread_) == Error::null()) {
function = owner.LookupFunction(func_name);
function = Resolver::ResolveFunction(Z, owner, func_name);
}
}

View file

@ -20,6 +20,7 @@
#include "vm/hash.h"
#include "vm/longjump.h"
#include "vm/object_store.h"
#include "vm/resolver.h"
#include "vm/reusable_handles.h"
#include "vm/scopes.h"
#include "vm/stack_frame_kbc.h"
@ -1444,17 +1445,16 @@ ObjectPtr BytecodeReaderHelper::ReadObjectContents(uint32_t header) {
}
FunctionPtr function = Function::null();
if (cls.EnsureIsFinalized(thread_) == Error::null()) {
function = cls.LookupFunction(name);
function = Resolver::ResolveFunction(Z, cls, name);
}
if (function == Function::null()) {
// When requesting a getter, also return method extractors.
if (Field::IsGetterName(name)) {
String& method_name =
String::Handle(Z, Field::NameFromGetter(name));
function = cls.LookupFunction(method_name);
function = Resolver::ResolveFunction(Z, cls, method_name);
if (function != Function::null()) {
function =
Function::Handle(Z, function).CreateMethodExtractor(name);
function = Function::Handle(Z, function).GetMethodExtractor(name);
if (function != Function::null()) {
return function;
}

View file

@ -1632,10 +1632,9 @@ Function& StreamingFlowGraphBuilder::FindMatchingFunction(
ArgumentsDescriptor args_desc(
Array::Handle(Z, ArgumentsDescriptor::NewBoxed(
type_args_len, argument_count, argument_names)));
Function& function =
Function::Handle(Z, Resolver::ResolveDynamicForReceiverClassAllowPrivate(
return Function::Handle(Z,
Resolver::ResolveDynamicForReceiverClassAllowPrivate(
klass, name, args_desc, /*allow_add=*/false));
return function;
}
bool StreamingFlowGraphBuilder::NeedsDebugStepCheck(const Function& function,
@ -2453,16 +2452,17 @@ static Function& GetNoSuchMethodOrDie(Thread* thread,
const Class& klass) {
Function& nsm_function = Function::Handle(zone);
Class& iterate_klass = Class::Handle(zone, klass.raw());
while (!iterate_klass.IsNull()) {
if (iterate_klass.EnsureIsFinalized(thread) == Error::null()) {
nsm_function =
iterate_klass.LookupDynamicFunction(Symbols::NoSuchMethod());
if (!iterate_klass.IsNull() &&
iterate_klass.EnsureIsFinalized(thread) == Error::null()) {
while (!iterate_klass.IsNull()) {
nsm_function = Resolver::ResolveDynamicFunction(zone, iterate_klass,
Symbols::NoSuchMethod());
if (!nsm_function.IsNull() && nsm_function.NumParameters() == 2 &&
nsm_function.NumTypeParameters() == 0) {
break;
}
iterate_klass = iterate_klass.SuperClass();
}
if (!nsm_function.IsNull() && nsm_function.NumParameters() == 2 &&
nsm_function.NumTypeParameters() == 0) {
break;
}
iterate_klass = iterate_klass.SuperClass();
}
// We are guaranteed to find noSuchMethod of class Object.
ASSERT(!nsm_function.IsNull());
@ -2544,9 +2544,9 @@ Fragment StreamingFlowGraphBuilder::BuildSuperPropertyGet(TokenPosition* p) {
// Search the superclass chain for the selector looking for either getter or
// method.
Function& function = Function::Handle(Z);
while (!klass.IsNull()) {
if (klass.EnsureIsFinalized(thread()) == Error::null()) {
function = klass.LookupDynamicFunction(method_name);
if (!klass.IsNull() && klass.EnsureIsFinalized(thread()) == Error::null()) {
while (!klass.IsNull()) {
function = Resolver::ResolveDynamicFunction(Z, klass, method_name);
if (!function.IsNull()) {
Function& target =
Function::ZoneHandle(Z, function.ImplicitClosureFunction());
@ -2555,10 +2555,10 @@ Fragment StreamingFlowGraphBuilder::BuildSuperPropertyGet(TokenPosition* p) {
// which captures `this`.
return BuildImplicitClosureCreation(target);
}
function = klass.LookupDynamicFunction(getter_name);
function = Resolver::ResolveDynamicFunction(Z, klass, getter_name);
if (!function.IsNull()) break;
klass = klass.SuperClass();
}
klass = klass.SuperClass();
}
Fragment instructions;
@ -2608,7 +2608,7 @@ Fragment StreamingFlowGraphBuilder::BuildSuperPropertySet(TokenPosition* p) {
Function& function = Function::Handle(Z);
if (klass.EnsureIsFinalized(thread()) == Error::null()) {
function = H.LookupDynamicFunction(klass, setter_name);
function = Resolver::ResolveDynamicFunction(Z, klass, setter_name);
}
Fragment instructions(MakeTemp());
@ -3874,8 +3874,8 @@ Fragment StreamingFlowGraphBuilder::BuildFutureNullValue(
ASSERT(!future.IsNull());
const auto& error = future.EnsureIsFinalized(thread());
ASSERT(error == Error::null());
const Function& constructor =
Function::ZoneHandle(Z, future.LookupFunction(Symbols::FutureValue()));
Function& constructor = Function::ZoneHandle(
Z, Resolver::ResolveFunction(Z, future, Symbols::FutureValue()));
ASSERT(!constructor.IsNull());
Fragment instructions;

View file

@ -3619,7 +3619,8 @@ FunctionPtr Function::GetMethodExtractor(const String& getter_name) const {
if (owner.EnsureIsFinalized(Thread::Current()) != Error::null()) {
return Function::null();
}
Function& result = Function::Handle(owner.LookupDynamicFunction(getter_name));
Function& result =
Function::Handle(owner.LookupDynamicFunctionUnsafe(getter_name));
if (result.IsNull()) {
result = CreateMethodExtractor(getter_name);
}
@ -5264,13 +5265,8 @@ bool Class::IsPrivate() const {
return Library::IsPrivate(String::Handle(Name()));
}
FunctionPtr Class::LookupDynamicFunction(const String& name) const {
return LookupFunction(name, kInstance);
}
FunctionPtr Class::LookupDynamicFunctionAllowAbstract(
const String& name) const {
return LookupFunction(name, kInstanceAllowAbstract);
FunctionPtr Class::LookupDynamicFunctionUnsafe(const String& name) const {
return LookupFunctionUnsafe(name, kInstance);
}
FunctionPtr Class::LookupDynamicFunctionAllowPrivate(const String& name) const {
@ -5278,7 +5274,7 @@ FunctionPtr Class::LookupDynamicFunctionAllowPrivate(const String& name) const {
}
FunctionPtr Class::LookupStaticFunction(const String& name) const {
return LookupFunction(name, kStatic);
return LookupFunctionUnsafe(name, kStatic);
}
FunctionPtr Class::LookupStaticFunctionAllowPrivate(const String& name) const {
@ -5286,7 +5282,7 @@ FunctionPtr Class::LookupStaticFunctionAllowPrivate(const String& name) const {
}
FunctionPtr Class::LookupConstructor(const String& name) const {
return LookupFunction(name, kConstructor);
return LookupFunctionUnsafe(name, kConstructor);
}
FunctionPtr Class::LookupConstructorAllowPrivate(const String& name) const {
@ -5294,21 +5290,21 @@ FunctionPtr Class::LookupConstructorAllowPrivate(const String& name) const {
}
FunctionPtr Class::LookupFactory(const String& name) const {
return LookupFunction(name, kFactory);
return LookupFunctionUnsafe(name, kFactory);
}
FunctionPtr Class::LookupFactoryAllowPrivate(const String& name) const {
return LookupFunctionAllowPrivate(name, kFactory);
}
FunctionPtr Class::LookupFunction(const String& name) const {
return LookupFunction(name, kAny);
}
FunctionPtr Class::LookupFunctionAllowPrivate(const String& name) const {
return LookupFunctionAllowPrivate(name, kAny);
}
FunctionPtr Class::LookupFunctionUnsafe(const String& name) const {
return LookupFunctionUnsafe(name, kAny);
}
// Returns true if 'prefix' and 'accessor_name' match 'name'.
static bool MatchesAccessorName(const String& name,
const char* prefix,
@ -5358,7 +5354,8 @@ FunctionPtr Class::CheckFunctionType(const Function& func, MemberKind kind) {
return Function::null();
}
FunctionPtr Class::LookupFunction(const String& name, MemberKind kind) const {
FunctionPtr Class::LookupFunctionUnsafe(const String& name,
MemberKind kind) const {
ASSERT(!IsNull());
Thread* thread = Thread::Current();
RELEASE_ASSERT(is_finalized());
@ -9066,9 +9063,11 @@ FunctionPtr Function::ImplicitClosureTarget(Zone* zone) const {
const auto& parent = Function::Handle(zone, parent_function());
const auto& func_name = String::Handle(zone, parent.name());
const auto& owner = Class::Handle(zone, parent.Owner());
const auto& error = owner.EnsureIsFinalized(Thread::Current());
Thread* thread = Thread::Current();
const auto& error = owner.EnsureIsFinalized(thread);
ASSERT(error == Error::null());
auto& target = Function::Handle(zone, owner.LookupFunction(func_name));
auto& target =
Function::Handle(zone, Resolver::ResolveFunction(zone, owner, func_name));
if (!target.IsNull() && (target.raw() != parent.raw())) {
DEBUG_ASSERT(Isolate::Current()->HasAttemptedReload());

View file

@ -1306,8 +1306,9 @@ class Class : public Object {
intptr_t FindImplicitClosureFunctionIndex(const Function& needle) const;
FunctionPtr ImplicitClosureFunctionFromIndex(intptr_t idx) const;
FunctionPtr LookupDynamicFunction(const String& name) const;
FunctionPtr LookupDynamicFunctionAllowAbstract(const String& name) const;
FunctionPtr LookupFunctionUnsafe(const String& name) const;
FunctionPtr LookupDynamicFunctionUnsafe(const String& name) const;
FunctionPtr LookupDynamicFunctionAllowPrivate(const String& name) const;
FunctionPtr LookupStaticFunction(const String& name) const;
FunctionPtr LookupStaticFunctionAllowPrivate(const String& name) const;
@ -1315,7 +1316,6 @@ class Class : public Object {
FunctionPtr LookupConstructorAllowPrivate(const String& name) const;
FunctionPtr LookupFactory(const String& name) const;
FunctionPtr LookupFactoryAllowPrivate(const String& name) const;
FunctionPtr LookupFunction(const String& name) const;
FunctionPtr LookupFunctionAllowPrivate(const String& name) const;
FunctionPtr LookupGetterFunction(const String& name) const;
FunctionPtr LookupSetterFunction(const String& name) const;
@ -1757,7 +1757,7 @@ class Class : public Object {
void InitEmptyFields();
static FunctionPtr CheckFunctionType(const Function& func, MemberKind kind);
FunctionPtr LookupFunction(const String& name, MemberKind kind) const;
FunctionPtr LookupFunctionUnsafe(const String& name, MemberKind kind) const;
FunctionPtr LookupFunctionAllowPrivate(const String& name,
MemberKind kind) const;
FieldPtr LookupField(const String& name, MemberKind kind) const;

View file

@ -198,7 +198,7 @@ void CallSiteResetter::RebindStaticTargets(const Bytecode& bytecode) {
new_lib_ = new_cls_.library();
new_function_ = new_lib_.LookupLocalFunction(name_);
} else {
new_function_ = new_cls_.LookupFunction(name_);
new_function_ = Resolver::ResolveFunction(zone_, new_cls_, name_);
}
if (!new_function_.IsNull() &&
(new_function_.is_static() == old_function.is_static()) &&
@ -538,6 +538,7 @@ void Class::PatchFieldsAndFunctions() const {
void Class::MigrateImplicitStaticClosures(IsolateReloadContext* irc,
const Class& new_cls) const {
const Array& funcs = Array::Handle(functions());
Thread* thread = Thread::Current();
Function& old_func = Function::Handle();
String& selector = String::Handle();
Function& new_func = Function::Handle();
@ -547,7 +548,7 @@ void Class::MigrateImplicitStaticClosures(IsolateReloadContext* irc,
old_func ^= funcs.At(i);
if (old_func.is_static() && old_func.HasImplicitClosureFunction()) {
selector = old_func.name();
new_func = new_cls.LookupFunction(selector);
new_func = Resolver::ResolveFunction(thread->zone(), new_cls, selector);
if (!new_func.IsNull() && new_func.is_static()) {
old_func = old_func.ImplicitClosureFunction();
old_closure = old_func.ImplicitStaticClosure();
@ -982,7 +983,7 @@ void CallSiteResetter::Reset(const ICData& ic) {
old_target_.kind() == FunctionLayout::kConstructor);
// This can be incorrect if the call site was an unqualified invocation.
new_cls_ = old_target_.Owner();
new_target_ = new_cls_.LookupFunction(name_);
new_target_ = Resolver::ResolveFunction(zone_, new_cls_, name_);
if (new_target_.kind() != old_target_.kind()) {
new_target_ = Function::null();
}

View file

@ -7,6 +7,7 @@
#include "vm/debugger.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/resolver.h"
#include "vm/stub_code.h"
#include "vm/symbols.h"
@ -260,7 +261,8 @@ static void AddFunctionServiceId(const JSONObject& jsobj,
}
// Regular functions known to their owner use their name (percent-encoded).
String& name = String::Handle(f.name());
if (cls.LookupFunction(name) == f.raw()) {
Thread* thread = Thread::Current();
if (Resolver::ResolveFunction(thread->zone(), cls, name) == f.raw()) {
const char* encoded_name = String::EncodeIRI(name);
if (cls.IsTopLevel()) {
const auto& library = Library::Handle(cls.library());

View file

@ -182,9 +182,11 @@ FunctionPtr ObjectStore::PrivateObjectLookup(const String& name) {
const Library& core_lib = Library::Handle(core_library());
const String& mangled = String::ZoneHandle(core_lib.PrivateName(name));
const Class& cls = Class::Handle(object_class());
const auto& error = cls.EnsureIsFinalized(Thread::Current());
Thread* thread = Thread::Current();
const auto& error = cls.EnsureIsFinalized(thread);
ASSERT(error == Error::null());
const Function& result = Function::Handle(cls.LookupDynamicFunction(mangled));
const Function& result = Function::Handle(
Resolver::ResolveDynamicFunction(thread->zone(), cls, mangled));
ASSERT(!result.IsNull());
return result.raw();
}

View file

@ -23,12 +23,15 @@
#include "vm/malloc_hooks.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/resolver.h"
#include "vm/simulator.h"
#include "vm/symbols.h"
#include "vm/unit_test.h"
namespace dart {
#define Z (thread->zone())
DECLARE_FLAG(bool, dual_map_code);
DECLARE_FLAG(bool, write_protect_code);
@ -124,7 +127,7 @@ ISOLATE_UNIT_TEST_CASE(Class) {
cls.Finalize();
function_name = String::New("Foo");
function = cls.LookupDynamicFunction(function_name);
function = Resolver::ResolveDynamicFunction(Z, cls, function_name);
EXPECT(function.IsNull());
function = cls.LookupStaticFunction(function_name);
EXPECT(!function.IsNull());
@ -132,7 +135,7 @@ ISOLATE_UNIT_TEST_CASE(Class) {
EXPECT_EQ(cls.raw(), function.Owner());
EXPECT(function.is_static());
function_name = String::New("baz");
function = cls.LookupDynamicFunction(function_name);
function = Resolver::ResolveDynamicFunction(Z, cls, function_name);
EXPECT(!function.IsNull());
EXPECT(function_name.Equals(String::Handle(function.name())));
EXPECT_EQ(cls.raw(), function.Owner());
@ -141,13 +144,13 @@ ISOLATE_UNIT_TEST_CASE(Class) {
EXPECT(function.IsNull());
function_name = String::New("foo");
function = cls.LookupDynamicFunction(function_name);
function = Resolver::ResolveDynamicFunction(Z, cls, function_name);
EXPECT(!function.IsNull());
EXPECT_EQ(0, function.num_fixed_parameters());
EXPECT(!function.HasOptionalParameters());
function_name = String::New("bar");
function = cls.LookupDynamicFunction(function_name);
function = Resolver::ResolveDynamicFunction(Z, cls, function_name);
EXPECT(!function.IsNull());
EXPECT_EQ(kNumFixedParameters, function.num_fixed_parameters());
EXPECT_EQ(kNumOptionalParameters, function.NumOptionalParameters());
@ -3717,10 +3720,11 @@ ISOLATE_UNIT_TEST_CASE(MirrorReference) {
}
static FunctionPtr GetFunction(const Class& cls, const char* name) {
const auto& error = cls.EnsureIsFinalized(Thread::Current());
Thread* thread = Thread::Current();
const auto& error = cls.EnsureIsFinalized(thread);
EXPECT(error == Error::null());
const Function& result = Function::Handle(
cls.LookupDynamicFunction(String::Handle(String::New(name))));
const Function& result = Function::Handle(Resolver::ResolveDynamicFunction(
Z, cls, String::Handle(String::New(name))));
EXPECT(!result.IsNull());
return result.raw();
}
@ -4173,10 +4177,12 @@ ISOLATE_UNIT_TEST_CASE(PrintJSONPrimitives) {
}
// Function reference
{
Thread* thread = Thread::Current();
JSONStream js;
Class& cls = Class::Handle(isolate->object_store()->bool_class());
const String& func_name = String::Handle(String::New("toString"));
Function& func = Function::Handle(cls.LookupFunction(func_name));
Function& func =
Function::Handle(Resolver::ResolveFunction(Z, cls, func_name));
ASSERT(!func.IsNull());
func.PrintJSON(&js, true);
ElideJSONSubstring("classes", js.ToCString(), buffer);

View file

@ -136,7 +136,7 @@ FunctionPtr Resolver::ResolveDynamicForReceiverClass(
bool allow_add) {
return ResolveDynamicForReceiverClassWithCustomLookup(
receiver_class, function_name, args_desc, allow_add,
std::mem_fn(&Class::LookupDynamicFunction));
std::mem_fn(&Class::LookupDynamicFunctionUnsafe));
}
FunctionPtr Resolver::ResolveDynamicForReceiverClassAllowPrivate(
@ -149,13 +149,31 @@ FunctionPtr Resolver::ResolveDynamicForReceiverClassAllowPrivate(
std::mem_fn(&Class::LookupDynamicFunctionAllowPrivate));
}
FunctionPtr Resolver::ResolveFunction(Zone* zone,
const Class& receiver_class,
const String& function_name) {
return ResolveDynamicAnyArgsWithCustomLookup(
zone, receiver_class, function_name, /*allow_add=*/false,
std::mem_fn(static_cast<FunctionPtr (Class::*)(const String&) const>(
&Class::LookupFunctionUnsafe)));
}
FunctionPtr Resolver::ResolveDynamicFunction(Zone* zone,
const Class& receiver_class,
const String& function_name) {
return ResolveDynamicAnyArgsWithCustomLookup(
zone, receiver_class, function_name, /*allow_add=*/false,
std::mem_fn(static_cast<FunctionPtr (Class::*)(const String&) const>(
&Class::LookupDynamicFunctionUnsafe)));
}
FunctionPtr Resolver::ResolveDynamicAnyArgs(Zone* zone,
const Class& receiver_class,
const String& function_name,
bool allow_add) {
return ResolveDynamicAnyArgsWithCustomLookup(
zone, receiver_class, function_name, allow_add,
std::mem_fn(&Class::LookupDynamicFunctionAllowPrivate));
std::mem_fn(&Class::LookupDynamicFunctionUnsafe));
}
FunctionPtr Resolver::ResolveDynamicAnyArgsAllowPrivate(

View file

@ -50,6 +50,17 @@ class Resolver : public AllStatic {
const String& function_name,
bool allow_add);
// Resolve instance function [function_name] with any args, it doesn't
// allow adding methods during resolution: [allow_add] is [false].
static FunctionPtr ResolveDynamicFunction(Zone* zone,
const Class& receiver_class,
const String& function_name);
// Resolve static or instance function [function_name] with any args, it
// doesn't allow adding methods during resolution: [allow_add] is [false].
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

View file

@ -2258,7 +2258,7 @@ static ObjectPtr InvokeCallThroughGetterOrNoSuchMethod(
// need to try to find a dyn:get:foo first (see assertion below)
if (function.IsNull()) {
if (cls.EnsureIsFinalized(thread) == Error::null()) {
function = cls.LookupDynamicFunction(function_name);
function = Resolver::ResolveDynamicFunction(zone, cls, function_name);
}
}
if (!function.IsNull()) {
@ -2318,14 +2318,15 @@ static ObjectPtr InvokeCallThroughGetterOrNoSuchMethod(
// If there is a function with the target name but mismatched arguments
// we need to call `receiver.noSuchMethod()`.
if (cls.EnsureIsFinalized(thread) == Error::null()) {
function = cls.LookupDynamicFunction(target_name);
function = Resolver::ResolveDynamicFunction(zone, cls, target_name);
}
if (!function.IsNull()) {
ASSERT(!function.AreValidArguments(args_desc, NULL));
break; // mismatch, invoke noSuchMethod
}
if (is_dynamic_call) {
function = cls.LookupDynamicFunction(demangled_target_name);
function =
Resolver::ResolveDynamicFunction(zone, cls, demangled_target_name);
if (!function.IsNull()) {
ASSERT(!function.AreValidArguments(args_desc, NULL));
break; // mismatch, invoke noSuchMethod
@ -2334,10 +2335,10 @@ static ObjectPtr InvokeCallThroughGetterOrNoSuchMethod(
// If there is a getter we need to call-through-getter.
if (is_dynamic_call) {
function = cls.LookupDynamicFunction(dyn_getter_name);
function = Resolver::ResolveDynamicFunction(zone, cls, dyn_getter_name);
}
if (function.IsNull()) {
function = cls.LookupDynamicFunction(getter_name);
function = Resolver::ResolveDynamicFunction(zone, cls, getter_name);
}
if (!function.IsNull()) {
const Array& getter_arguments = Array::Handle(Array::New(1));
@ -2564,7 +2565,8 @@ static void HandleStackOverflowTestCases(Thread* thread) {
Library::Handle(isolate->object_store()->_internal_library());
const Class& cls = Class::Handle(
lib.LookupClass(String::Handle(String::New("VMLibraryHooks"))));
const Function& func = Function::Handle(cls.LookupFunction(
const Function& func = Function::Handle(Resolver::ResolveFunction(
thread->zone(), cls,
String::Handle(String::New("get:platformScript"))));
Object& result = Object::Handle(
DartEntry::InvokeFunction(func, Object::empty_array()));

View file

@ -39,6 +39,7 @@
#include "vm/port.h"
#include "vm/profiler.h"
#include "vm/profiler_service.h"
#include "vm/resolver.h"
#include "vm/reusable_handles.h"
#include "vm/service_event.h"
#include "vm/service_isolate.h"
@ -1725,7 +1726,9 @@ static ObjectPtr LookupClassMembers(Thread* thread,
}
if (strcmp(parts[2], "functions") == 0) {
// Function ids look like: "classes/17/functions/name"
const auto& function = Function::Handle(klass.LookupFunction(id));
const auto& function =
Function::Handle(Resolver::ResolveFunction(zone, klass, id));
if (function.IsNull()) {
return Object::sentinel().raw();
}

View file

@ -18,6 +18,7 @@
#include "vm/os.h"
#include "vm/port.h"
#include "vm/profiler.h"
#include "vm/resolver.h"
#include "vm/service.h"
#include "vm/unit_test.h"
@ -119,8 +120,8 @@ static ArrayPtr EvalF(Dart_Handle lib, const char* fmt, ...) {
}
static FunctionPtr GetFunction(const Class& cls, const char* name) {
const Function& result = Function::Handle(
cls.LookupDynamicFunction(String::Handle(String::New(name))));
const Function& result = Function::Handle(Resolver::ResolveDynamicFunction(
Thread::Current()->zone(), cls, String::Handle(String::New(name))));
EXPECT(!result.IsNull());
return result.raw();
}