Top


定義場所(file name)

hotspot/src/share/vm/classfile/classFileParser.cpp

名前(function name)

objArrayHandle ClassFileParser::parse_interfaces(constantPoolHandle cp,
                                                 int length,
                                                 Handle class_loader,
                                                 Handle protection_domain,
                                                 Symbol* class_name,
                                                 TRAPS) {

本体部(body)

  {- -------------------------------------------
  (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.