vim art
/
runtime
/
/
mirror
/
class
.cc
template <PointerSize kPointerSize,
bool
kTransactionActive>
ObjPtr<Method> Class::GetDeclaredMethodInternal(
Thread
*
self
,
ObjPtr<Class> klass,
ObjPtr<String> name,
ObjPtr<ObjectArray<Class>> args,
const std::function<hiddenapi::AccessContext()>& fn_get_access_context) {
/
/
Covariant
return
types (
or
smali) permit the
class
to define
/
/
multiple methods with the same name
and
parameter types.
/
/
Prefer (
in
decreasing order of importance):
/
/
1
) non
-
hidden method over hidden
/
/
2
) virtual methods over direct
/
/
3
) non
-
synthetic methods over synthetic
/
/
We never
return
miranda methods that were synthesized by the runtime.
StackHandleScope<
3
> hs(
self
);
auto h_method_name
=
hs.NewHandle(name);
if
(UNLIKELY(h_method_name
=
=
nullptr)) {
ThrowNullPointerException(
"name == null"
);
return
nullptr;
}
auto h_args
=
hs.NewHandle(args);
Handle<Class> h_klass
=
hs.NewHandle(klass);
constexpr hiddenapi::AccessMethod access_method
=
hiddenapi::AccessMethod::kNone;
ArtMethod
*
result
=
nullptr;
bool
result_hidden
=
false;
for
(auto& m : h_klass
-
>GetDeclaredVirtualMethods(kPointerSize)) {
/
*
4.
遍历virtual method
*
/
if
(m.IsMiranda()) {
continue
;
}
auto
*
np_method
=
m.GetInterfaceMethodIfProxy(kPointerSize);
/
/
May cause thread suspension.
ObjPtr<String> np_name
=
np_method
-
>ResolveNameString();
if
(!np_name
-
>Equals(h_method_name.Get()) || !np_method
-
>EqualParameters(h_args)) {
/
*
5.
判断方法名与参数类型
*
/
if
(UNLIKELY(
self
-
>IsExceptionPending())) {
return
nullptr;
}
continue
;
}
bool
m_hidden
=
hiddenapi::ShouldDenyAccessToMember(&m, fn_get_access_context, access_method);
/
*
6.
调用ShouldDenyAccessToMember
*
/
if
(!m_hidden && !m.IsSynthetic()) {
/
/
Non
-
hidden, virtual, non
-
synthetic. Best possible result, exit early.
return
Method::CreateFromArtMethod<kPointerSize, kTransactionActive>(
self
, &m);
}
else
if
(IsMethodPreferredOver(result, result_hidden, &m, m_hidden)) {
/
/
Remember as potential result.
result
=
&m;
result_hidden
=
m_hidden;
}
}
if
((result !
=
nullptr) && !result_hidden) {
/
/
We have
not
found a non
-
hidden, virtual, non
-
synthetic method, but
/
/
if
we have found a non
-
hidden, virtual, synthetic method, we cannot
/
/
do better than that later.
DCHECK(!result
-
>IsDirect());
DCHECK(result
-
>IsSynthetic());
}
else
{
for
(auto& m : h_klass
-
>GetDirectMethods(kPointerSize)) {
/
*
7.
遍历direct method
*
/
auto modifiers
=
m.GetAccessFlags();
if
((modifiers & kAccConstructor) !
=
0
) {
continue
;
}
auto
*
np_method
=
m.GetInterfaceMethodIfProxy(kPointerSize);
/
/
May cause thread suspension.
ObjPtr<String> np_name
=
np_method
-
>ResolveNameString();
if
(np_name
=
=
nullptr) {
self
-
>AssertPendingException();
return
nullptr;
}
if
(!np_name
-
>Equals(h_method_name.Get()) || !np_method
-
>EqualParameters(h_args)) {
/
*
8.
判断方法名与参数类型
*
/
if
(UNLIKELY(
self
-
>IsExceptionPending())) {
return
nullptr;
}
continue
;
}
DCHECK(!m.IsMiranda());
/
/
Direct methods cannot be miranda methods.
bool
m_hidden
=
hiddenapi::ShouldDenyAccessToMember(&m, fn_get_access_context, access_method);
/
*
9.
调用ShouldDenyAccessToMember
*
/
if
(!m_hidden && !m.IsSynthetic()) {
/
/
Non
-
hidden, direct, non
-
synthetic.
Any
virtual result could only have been
/
/
hidden, therefore this
is
the best possible match. Exit now.
DCHECK((result
=
=
nullptr) || result_hidden);
return
Method::CreateFromArtMethod<kPointerSize, kTransactionActive>(
self
, &m);
}
else
if
(IsMethodPreferredOver(result, result_hidden, &m, m_hidden)) {
/
/
Remember as potential result.
result
=
&m;
result_hidden
=
m_hidden;
}
}
}
return
result !
=
nullptr
? Method::CreateFromArtMethod<kPointerSize, kTransactionActive>(
self
, result)
: nullptr;
}