Top


定義場所(file name)

hotspot/src/share/vm/interpreter/linkResolver.cpp

説明(description)

// throws runtime exceptions

名前(function name)

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) {

本体部(body)

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