hotspot/src/share/vm/interpreter/linkResolver.cpp
// throws runtime exceptions
void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass,
Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS) {
{- -------------------------------------------
(1) check_null_and_abstract 引数が true の場合はチェックを行う.
レシーバーが null であれば NullPointerException.
---------------------------------------- -}
// check if receiver exists
if (check_null_and_abstract && recv.is_null()) {
THROW(vmSymbols::java_lang_NullPointerException());
}
{- -------------------------------------------
(1) レシーバーが対象メソッドの定義クラスと継承関係になければ IncompatibleClassChangeError
---------------------------------------- -}
// check if receiver klass implements the resolved interface
if (!recv_klass->is_subtype_of(resolved_klass())) {
ResourceMark rm(THREAD);
char buf[200];
jio_snprintf(buf, sizeof(buf), "Class %s does not implement the requested interface %s",
(Klass::cast(recv_klass()))->external_name(),
(Klass::cast(resolved_klass()))->external_name());
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
}
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
// do lookup based on receiver klass
methodHandle sel_method;
lookup_instance_method_in_klasses(sel_method, recv_klass,
resolved_method->name(),
resolved_method->signature(), CHECK);
{- -------------------------------------------
(1) 解決結果のメソッドが定義されていなければ AbstractMethodError.
---------------------------------------- -}
// check if method exists
if (sel_method.is_null()) {
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()),
resolved_method->name(),
resolved_method->signature()));
}
{- -------------------------------------------
(1) 解決結果が public method でなければ IllegalAccessError
---------------------------------------- -}
// check if public
if (!sel_method->is_public()) {
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()),
sel_method->name(),
sel_method->signature()));
}
{- -------------------------------------------
(1) check_null_and_abstract 引数が true の場合はチェックを行う.
解決結果が abstract method であれば AbstractMethodError.
---------------------------------------- -}
// check if abstract
if (check_null_and_abstract && sel_method->is_abstract()) {
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()),
sel_method->name(),
sel_method->signature()));
}
{- -------------------------------------------
(1) CallInfo::set_interface() を呼んで,
引数で渡された CallInfo オブジェクト内に
解決結果をセットする
---------------------------------------- -}
// setup result
result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, CHECK);
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.