hotspot/src/share/vm/classfile/classFileParser.cpp
objArrayHandle ClassFileParser::parse_interfaces(constantPoolHandle cp,
int length,
Handle class_loader,
Handle protection_domain,
Symbol* class_name,
TRAPS) {
{- -------------------------------------------
(1)
---------------------------------------- -}
ClassFileStream* cfs = stream();
assert(length > 0, "only called for length>0");
objArrayHandle nullHandle;
objArrayOop interface_oop = oopFactory::new_system_objArray(length, CHECK_(nullHandle));
objArrayHandle interfaces (THREAD, interface_oop);
{- -------------------------------------------
(1) 引数で指定された length 分 (= パース対象のクラスが実装しているインターフェースの個数分) だけループ
(このループ内でインターフェース情報の読み込み, および確認処理を行う)
---------------------------------------- -}
int index;
for (index = 0; index < length; index++) {
{- -------------------------------------------
(1.1) 次のインターフェースを指す index を取得し,
その index 値が Constant Pool 内に収まっており,
class を指していることを確認.
---------------------------------------- -}
u2 interface_index = cfs->get_u2(CHECK_(nullHandle));
KlassHandle interf;
check_property(
valid_cp_range(interface_index, cp->length()) &&
is_klass_reference(cp, interface_index),
"Interface name has bad constant pool index %u in class file %s",
interface_index, CHECK_(nullHandle));
{- -------------------------------------------
(1.1) もしまだ resolve されてなければ SystemDictionary::resolve_super_or_fail() で resolve する.
(ここで ClassCircularityErrors もチェック).
(この時点で resolve されているのはどういう状況なんだろう? #TODO)
---------------------------------------- -}
if (cp->tag_at(interface_index).is_klass()) {
interf = KlassHandle(THREAD, cp->resolved_klass_at(interface_index));
} else {
Symbol* unresolved_klass = cp->klass_name_at(interface_index);
// Don't need to check legal name because it's checked when parsing constant pool.
// But need to make sure it's not an array type.
guarantee_property(unresolved_klass->byte_at(0) != JVM_SIGNATURE_ARRAY,
"Bad interface name in class file %s", CHECK_(nullHandle));
// Call resolve_super so classcircularity is checked
klassOop k = SystemDictionary::resolve_super_or_fail(class_name,
unresolved_klass, class_loader, protection_domain,
false, CHECK_(nullHandle));
interf = KlassHandle(THREAD, k);
{- -------------------------------------------
(1.1) ?? #TODO
(この段階でいきなり Constant Pool を書き換える処理?)
---------------------------------------- -}
if (LinkWellKnownClasses) // my super type is well known to me
cp->klass_at_put(interface_index, interf()); // eagerly resolve
}
{- -------------------------------------------
(1.1) index の指している先が interface かどうかを確認.
違ったら IncompatibleClassChangeError.
---------------------------------------- -}
if (!Klass::cast(interf())->is_interface()) {
THROW_MSG_(vmSymbols::java_lang_IncompatibleClassChangeError(), "Implementing class", nullHandle);
}
{- -------------------------------------------
(1.1) 結果を格納する配列に, この index とインターフェースを追加.
---------------------------------------- -}
interfaces->obj_at_put(index, interf());
}
{- -------------------------------------------
(1) 次に, 宣言されているインターフェースが重複していないかどうかを以下のようにチェックする.
---------------------------------------- -}
{- -------------------------------------------
(1.1) _need_verify が立っていなかったり, インターフェースが1個しかなければ, ここでリターン
---------------------------------------- -}
if (!_need_verify || length <= 1) {
return interfaces;
}
{- -------------------------------------------
(1.1) 重複をチェックする.
もし重複していたら classfile_parse_error() を呼んで ClassFormatError にする
---------------------------------------- -}
// Check if there's any duplicates in interfaces
ResourceMark rm(THREAD);
NameSigHash** interface_names = NEW_RESOURCE_ARRAY_IN_THREAD(
THREAD, NameSigHash*, HASH_ROW_SIZE);
initialize_hashtable(interface_names);
bool dup = false;
{
debug_only(No_Safepoint_Verifier nsv;)
for (index = 0; index < length; index++) {
klassOop k = (klassOop)interfaces->obj_at(index);
Symbol* name = instanceKlass::cast(k)->name();
// If no duplicates, add (name, NULL) in hashtable interface_names.
if (!put_after_lookup(name, NULL, interface_names)) {
dup = true;
break;
}
}
}
if (dup) {
classfile_parse_error("Duplicate interface name in class file %s",
CHECK_(nullHandle));
}
{- -------------------------------------------
(1) 読み込んだインターフェース情報をリターン
---------------------------------------- -}
return interfaces;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.