Main Page | Namespace List | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

linkage.c

Go to the documentation of this file.
00001 /*!
00002  * @file linkage.c
00003  *
00004  * @brief Late binding linkages between classes.
00005  *
00006  * This logic should be called each and every time a class is
00007  * loaded or unloaded.  When a new class is loaded, existing
00008  * classes may have unresolved linkages to them that need to
00009  * be filled in to point to the new class.  Likewise, when a
00010  * class is unloaded, the remaining classes need to have the
00011  * linkages removed.  In this manner, the class linkage status
00012  * will stay current.
00013  *
00014  *
00015  * @section Control
00016  *
00017  * \$URL: https://svn.apache.org/path/name/linkage.c $ \$Id: linkage.c 0 09/28/2005 dlydick $
00018  *
00019  * Copyright 2005 The Apache Software Foundation
00020  * or its licensors, as applicable.
00021  *
00022  * Licensed under the Apache License, Version 2.0 ("the License");
00023  * you may not use this file except in compliance with the License.
00024  * You may obtain a copy of the License at
00025  *
00026  *     http://www.apache.org/licenses/LICENSE-2.0
00027  *
00028  * Unless required by applicable law or agreed to in writing,
00029  * software distributed under the License is distributed on an
00030  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
00031  * either express or implied.
00032  *
00033  * See the License for the specific language governing permissions
00034  * and limitations under the License.
00035  *
00036  * @version \$LastChangedRevision: 0 $
00037  *
00038  * @date \$LastChangedDate: 09/28/2005 $
00039  *
00040  * @author \$LastChangedBy: dlydick $
00041  *         Original code contributed by Daniel Lydick on 09/28/2005.
00042  *
00043  * @section Reference
00044  *
00045  */
00046 
00047 #include "arch.h"
00048 ARCH_COPYRIGHT_APACHE(linkage, c, "$URL: https://svn.apache.org/path/name/linkage.c $ $Id: linkage.c 0 09/28/2005 dlydick $");
00049 
00050 #include "jvmcfg.h"
00051 #include "cfmacros.h"
00052 #include "classfile.h"
00053 #include "attribute.h"
00054 #include "exit.h"
00055 #include "field.h"
00056 #include "gc.h" 
00057 #include "jvm.h"
00058 #include "jvmclass.h"
00059 #include "linkage.h"
00060 #include "method.h"
00061 #include "native.h"
00062 #include "util.h"
00063 
00064 
00065 /*!
00066  * @brief Resolve class table and object table linkages for a class
00067  * file, typically one just loaded by
00068  * @link #class_static_new() class_static_new()@endlink
00069  *
00070  *
00071  * @param  clsidx   Class table index to class to resolve against
00072  *                  all loaded classes.
00073  *
00074  * @param find_registerNatives When @link #rtrue rtrue@endlink, will
00075  *                  return the ordinal for
00076  *                  @link #JVMCFG_JLOBJECT_NMO_REGISTER 
00077                     JVMCFG_JLOBJECT_NMO_REGISTER@endlink and
00078  *                  @link #JVMCFG_JLOBJECT_NMO_UNREGISTER 
00079                     JVMCFG_JLOBJECT_NMO_UNREGISTER@endlink
00080  *                  as well as the other ordinals.  Once JVM
00081  *                  initialization is complete, this should always
00082  *                  be @link #rfalse rfalse@endlink because all
00083  *                  future classes should @e never have local ordinals.
00084  *
00085  *
00086  * @returns @link #rtrue rtrue@endlink if class was completely
00087  *          resolved, @link #rfalse rfalse@endlink otherwise.
00088  *
00089  */
00090 
00091 rboolean linkage_resolve_class(jvm_class_index clsidx,
00092                                rboolean        find_registerNatives)
00093 {
00094     if (jvm_class_index_null == clsidx)
00095     {
00096         /*!
00097          * @link #rtrue rtrue@endlink/@link #rfalse rfalse@endlink
00098          * irrelevant here
00099          */
00100         return(rfalse);
00101     }
00102 
00103     /* If class is not present, cannot resolve linkages */
00104     if (!(CLASS_STATUS_INUSE & CLASS(clsidx).status))
00105     {
00106         return(rfalse);
00107     }
00108 
00109     /* If class is fully linked, there is no need to do it again */
00110     if (CLASS_STATUS_LINKED & CLASS(clsidx).status)
00111     {
00112         return(rtrue);
00113     }
00114 
00115     /*
00116      * Try to find @e one instance of a class not yet loaded.  If found,
00117      * then this class cannot be linked to it, so set
00118      * @link #rfalse rfalse@endlink.  This result will be stored in the
00119      * </b><code>CLASS(clsidx)->status</code></b>
00120      * as the @link #CLASS_STATUS_LINKED CLASS_STATUS_LINKED@endlink
00121      * bit, either @link #rtrue rtrue@endlink or
00122      * @link #rfalse rfalse@endlink.
00123      */
00124     rboolean class_fully_linked = rtrue;
00125 
00126     /*
00127      * Scan through constant_pool, resolving any missing items
00128      * that might now be available.
00129      */
00130 
00131     ClassFile *pcfs = CLASS_OBJECT_LINKAGE(clsidx)->pcfs;
00132 
00133     jvm_constant_pool_index cpidx;
00134     for (cpidx = CONSTANT_CP_START_INDEX;
00135          cpidx < pcfs->constant_pool_count + CONSTANT_CP_START_INDEX -1;
00136          cpidx++)
00137     {
00138         jvm_class_index        clsidxFIND;
00139         jvm_field_index        fldidxFIND;
00140         jvm_field_lookup_index fluidxFIND;
00141 
00142         jvm_method_index       mthidxFIND;
00143         jvm_attribute_index    atridxFIND;
00144 
00145         cp_info_dup *pcpd = pcfs->constant_pool[cpidx];
00146 
00147         CONSTANT_Class_info              *pcpd_Class;
00148         CONSTANT_Fieldref_info           *pcpd_Fieldref;
00149         CONSTANT_Methodref_info          *pcpd_Methodref;
00150         CONSTANT_InterfaceMethodref_info *pcpd_InterfaceMethodref;
00151         CONSTANT_NameAndType_info        *pcpd_NameAndType;
00152 
00153         cp_info_dup *clsname;
00154 
00155         switch (CP_TAG(pcfs, cpidx))
00156         {
00157             case CONSTANT_Class:
00158 
00159                 pcpd_Class = PTR_THIS_CP_Class(pcpd);
00160 
00161                 /* Only resolve this CP slot if it is not yet done. */
00162                 if (jvm_class_index_null ==
00163                     pcpd_Class->LOCAL_Class_binding.clsidxJVM)
00164                 {
00165                     clsname =
00166                         pcfs->constant_pool[pcpd_Class->name_index];
00167 
00168                     clsidxFIND = class_find_by_cp_entry(clsname);
00169 
00170                     if (jvm_class_index_null == clsidxFIND)
00171                     {
00172                         /* Class not yet loaded in memory */
00173                         class_fully_linked = rfalse;
00174                     }
00175                     else
00176                     {
00177                         PTR_THIS_CP_Class(pcpd)
00178                            ->LOCAL_Class_binding.clsidxJVM = clsidxFIND;
00179 
00180                         /* Add reference unless it references itself */
00181                         if (clsidx != clsidxFIND)
00182                         {
00183                             (rvoid) GC_CLASS_MKREF_FROM_CLASS(
00184                                         clsidx,
00185                                         clsidxFIND);
00186                         }
00187                     }
00188                 }
00189                 break;
00190 
00191             case CONSTANT_Fieldref:
00192 
00193                 pcpd_Fieldref = PTR_THIS_CP_Fieldref(pcpd);
00194 
00195                 /* Only resolve this CP slot if it is not yet done. */
00196                 if (jvm_class_index_null ==
00197                     pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM)
00198                 {
00199                     pcpd_Class =
00200                         PTR_THIS_CP_Class(pcfs->constant_pool
00201                                          [pcpd_Fieldref->class_index]);
00202 
00203                     clsname =
00204                         pcfs->constant_pool[pcpd_Class->name_index];
00205 
00206                     clsidxFIND = class_find_by_cp_entry(clsname);
00207 
00208                     pcpd_Fieldref
00209                         ->LOCAL_Fieldref_binding.clsidxJVM = clsidxFIND;
00210 
00211                     if (jvm_class_index_null == clsidxFIND)
00212                     {
00213                         /* Class not yet loaded in memory */
00214                         class_fully_linked = rfalse;
00215                     }
00216                     else
00217                     {
00218                         pcpd_NameAndType =
00219                             PTR_THIS_CP_NameAndType(
00220                                 pcfs->constant_pool
00221                                   [pcpd_Fieldref->name_and_type_index]);
00222 
00223                         fldidxFIND =
00224                             field_find_by_cp_entry(
00225                                 clsidxFIND,
00226                                 pcfs->constant_pool
00227                                     [pcpd_NameAndType->name_index],
00228                                 pcfs->constant_pool
00229                                   [pcpd_NameAndType->descriptor_index]);
00230 
00231                         if (jvm_field_index_bad == fldidxFIND)
00232                         {
00233                             /* Field not found in class-- fatal error */
00234                             exit_throw_exception(EXIT_JVM_CLASS,
00235                                    JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR);
00236 /*NOTREACHED*/
00237 #if 0
00238                             pcpd_Fieldref
00239                                 ->LOCAL_Fieldref_binding.fluidxJVM =
00240                                     jvm_field_lookup_index_bad;
00241 
00242                             pcpd_Fieldref
00243                                 ->LOCAL_Fieldref_binding.oiflagJVM =
00244                                     rneither_true_nor_false;
00245 
00246                             pcpd_Fieldref
00247                                 ->LOCAL_Fieldref_binding.jvaluetypeJVM =
00248                                     LOCAL_BASETYPE_ERROR;
00249 
00250                             /* No point processing ACC_STATIC bit */
00251                             continue;
00252 #endif
00253                         }
00254 
00255                         /*
00256                          * Now check if ACC_STATIC or not and store
00257                          * the proper type of field lookup index.
00258                          */
00259                         if (FIELD(clsidxFIND, fldidxFIND)
00260                               ->access_flags & ACC_STATIC)
00261                         {
00262                             fluidxFIND =
00263             field_index_get_class_static_lookup(clsidxFIND, fldidxFIND);
00264 
00265                         }
00266                         else
00267                         {
00268                             fluidxFIND =
00269          field_index_get_object_instance_lookup(clsidxFIND, fldidxFIND);
00270 
00271                         }
00272 
00273                         pcpd_Fieldref
00274                             ->LOCAL_Fieldref_binding.fluidxJVM =
00275                                 fluidxFIND;
00276 
00277                         if (jvm_field_lookup_index_bad == fluidxFIND)
00278                         {
00279                             /* Field not found in class-- fatal error */
00280                             exit_throw_exception(EXIT_JVM_CLASS,
00281                                    JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR);
00282 /*NOTREACHED*/
00283 
00284                             pcpd_Fieldref
00285                                 ->LOCAL_Fieldref_binding.oiflagJVM =
00286                                     rneither_true_nor_false;
00287 
00288                             pcpd_Fieldref
00289                                 ->LOCAL_Fieldref_binding.jvaluetypeJVM =
00290                                     LOCAL_BASETYPE_ERROR;
00291 
00292                             /*
00293                              * Don't have valid @b oiflagJVM or
00294                              * @b jvaluetypeJVM result
00295                              */
00296                             continue;
00297                         }
00298 
00299                         pcpd_Fieldref
00300                             ->LOCAL_Fieldref_binding.oiflagJVM =
00301                                 (FIELD(clsidxFIND, fldidxFIND)
00302                                    ->access_flags & ACC_STATIC)
00303                                 ? rfalse
00304                                 : rtrue;
00305 
00306                         cp_info_dup *pfldesc_dup =
00307                            CLASS_OBJECT_LINKAGE(clsidxFIND)
00308                              ->pcfs
00309                                ->constant_pool
00310                                  [FIELD(clsidxFIND, fldidxFIND)
00311                                     ->descriptor_index];
00312 
00313                         CONSTANT_Utf8_info *pfldesc =
00314                                           PTR_THIS_CP_Utf8(pfldesc_dup);
00315 
00316                         /*!
00317                          * @todo What needs to happen when base type
00318                          *       is BASETYPE_ARRAY or BASETYPE_ERROR
00319                          *       or BASETYPE_VOID?
00320                          */
00321                         pcpd_Fieldref
00322                             ->LOCAL_Fieldref_binding.jvaluetypeJVM =
00323 
00324                                 pfldesc->bytes[0];
00325 
00326                         /* Add reference unless it references itself */
00327                         if (clsidx != clsidxFIND)
00328                         {
00329                             (rvoid) GC_CLASS_MKREF_FROM_CLASS(
00330                                         clsidx,
00331                                         clsidxFIND);
00332                         }
00333                     }
00334                 }
00335                 break;
00336 
00337             case CONSTANT_Methodref:
00338 
00339                 pcpd_Methodref = PTR_THIS_CP_Methodref(pcpd);
00340 
00341                 /* Only resolve this CP slot if it is not yet done. */
00342                 if (jvm_class_index_null ==
00343                     pcpd_Methodref->LOCAL_Methodref_binding.clsidxJVM)
00344                 {
00345                     pcpd_Class =
00346                         PTR_THIS_CP_Class(pcfs->constant_pool
00347                                          [pcpd_Methodref->class_index]);
00348 
00349                     clsname =
00350                         pcfs->constant_pool[pcpd_Class->name_index];
00351 
00352                     clsidxFIND = class_find_by_cp_entry(clsname);
00353 
00354                     pcpd_Methodref
00355                         ->LOCAL_Methodref_binding.clsidxJVM =clsidxFIND;
00356 
00357                     if (jvm_class_index_null == clsidxFIND)
00358                     {
00359                         /* Class not yet loaded in memory */
00360                         class_fully_linked = rfalse;
00361                     }
00362                     else
00363                     {
00364                         pcpd_NameAndType =
00365                             PTR_THIS_CP_NameAndType(
00366                                 pcfs->constant_pool
00367                                  [pcpd_Methodref->name_and_type_index]);
00368 
00369                         mthidxFIND =
00370                             method_find_by_cp_entry(
00371                                 clsidxFIND,
00372                                 pcfs->constant_pool
00373                                     [pcpd_NameAndType->name_index],
00374                                 pcfs->constant_pool
00375                                   [pcpd_NameAndType->descriptor_index]);
00376 
00377                         pcpd_Methodref
00378                             ->LOCAL_Methodref_binding.mthidxJVM =
00379                                 mthidxFIND;
00380 
00381                         if (jvm_method_index_bad == mthidxFIND)
00382                         {
00383                             /* Method not found in class-- fatal error*/
00384                             exit_throw_exception(EXIT_JVM_CLASS,
00385                                   JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
00386 /*NOTREACHED*/
00387                         }
00388 
00389                         /*
00390                          * Now check if Code_attribute is present
00391                          * and store its index.  First check if native
00392                          * and insert native method ordinal if so.
00393                          */
00394 
00395                         if (ACC_NATIVE &
00396                             METHOD(clsidxFIND,mthidxFIND)->access_flags)
00397                         {
00398                             atridxFIND = jvm_attribute_index_native;
00399 
00400                             pcpd_Methodref
00401                               ->LOCAL_Methodref_binding
00402                                   .nmordJVM =
00403                                 native_locate_local_method(
00404                                         pcfs,
00405                                         pcpd_Class->name_index,
00406                                         pcpd_NameAndType->name_index,
00407                                         pcpd_NameAndType
00408                                           ->descriptor_index,
00409                                         find_registerNatives);
00410                         }
00411                         else
00412                         {
00413                             atridxFIND =
00414                                 attribute_find_in_method_by_enum(
00415                                     clsidxFIND,
00416                                     mthidxFIND,
00417                                     LOCAL_CODE_ATTRIBUTE);
00418                         }
00419 
00420                         pcpd_Methodref
00421                             ->LOCAL_Methodref_binding.codeatridxJVM =
00422                                 atridxFIND;
00423 
00424                         if (jvm_attribute_index_bad == atridxFIND)
00425                         {
00426                             /* Code not found in method-- fatal error */
00427                             exit_throw_exception(EXIT_JVM_ATTRIBUTE,
00428                                   JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
00429 /*NOTREACHED*/
00430                         }
00431 
00432                         /*
00433                          * Now check if Exceptions attribute is
00434                          * present and store its index.
00435                          */
00436 
00437                         atridxFIND =
00438                             attribute_find_in_method_by_enum(
00439                                 clsidxFIND,
00440                                 mthidxFIND,
00441                                 LOCAL_EXCEPTIONS_ATTRIBUTE);
00442 
00443                         pcpd_Methodref
00444                             ->LOCAL_Methodref_binding.excpatridxJVM =
00445                                 atridxFIND;
00446 
00447                         if (jvm_attribute_index_bad == atridxFIND)
00448                         {
00449                             /* It is OKAY to not have exceptions */
00450                         }
00451  
00452                         /* Add reference unless it references itself */
00453                         if (clsidx != clsidxFIND)
00454                         {
00455                             (rvoid) GC_CLASS_MKREF_FROM_CLASS(
00456                                         clsidx,
00457                                         clsidxFIND);
00458                         }
00459                     }
00460                 }
00461                 break;
00462 
00463             case CONSTANT_InterfaceMethodref:
00464 
00465                 pcpd_InterfaceMethodref =
00466                     PTR_THIS_CP_InterfaceMethodref(pcpd);
00467 
00468                 /* Only resolve this CP slot if it is not yet done. */
00469                 if (jvm_class_index_null ==
00470                     pcpd_InterfaceMethodref
00471                         ->LOCAL_InterfaceMethodref_binding.clsidxJVM)
00472                 {
00473                     pcpd_Class =
00474                         PTR_THIS_CP_Class(pcfs->constant_pool
00475                                 [pcpd_InterfaceMethodref->class_index]);
00476                     clsname =
00477                         pcfs->constant_pool[pcpd_Class->name_index];
00478 
00479                     clsidxFIND = class_find_by_cp_entry(clsname);
00480 
00481                     pcpd_InterfaceMethodref
00482                         ->LOCAL_InterfaceMethodref_binding.clsidxJVM =
00483                             clsidxFIND;
00484 
00485                     if (jvm_class_index_null == clsidxFIND)
00486                     {
00487                         /* Class not yet loaded in memory */
00488                         class_fully_linked = rfalse;
00489                     }
00490                     else
00491                     {
00492                         pcpd_NameAndType =
00493                             PTR_THIS_CP_NameAndType(
00494                                 pcfs->constant_pool
00495                                 [pcpd_InterfaceMethodref
00496                                   ->name_and_type_index]);
00497 
00498                         mthidxFIND =
00499                             method_find_by_cp_entry(
00500                                 clsidxFIND,
00501                                 pcfs->constant_pool
00502                                     [pcpd_NameAndType->name_index],
00503                                 pcfs->constant_pool
00504                                   [pcpd_NameAndType->descriptor_index]);
00505 
00506                         pcpd_InterfaceMethodref
00507                             ->LOCAL_InterfaceMethodref_binding
00508                               .mthidxJVM =
00509                                   mthidxFIND;
00510 
00511                         if (jvm_method_index_bad == mthidxFIND)
00512                         {
00513                             /* Method not found in class-- fatal error*/
00514                             exit_throw_exception(EXIT_JVM_CLASS,
00515                                   JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
00516 /*NOTREACHED*/
00517                         }
00518 
00519                         /*
00520                          * Now check if Code_attribute is present
00521                          * and store its index.  First check if native
00522                          * and insert native method ordinal if so.
00523                          */
00524 
00525                         if (ACC_NATIVE &
00526                             METHOD(clsidxFIND,mthidxFIND)->access_flags)
00527                         {
00528                             atridxFIND = jvm_attribute_index_native;
00529 
00530                             /*!
00531                              * @todo Should this instance permit
00532                              *       use of @b find_registerNatives
00533                              *       since interaces are not a part
00534                              *       of the JVM startup, just a few
00535                              *       foundational classes?  Should
00536                              *       it just be
00537                              *       @link #rfalse rfalse@endlink
00538                              *       instead?
00539                              */
00540                             pcpd_InterfaceMethodref
00541                               ->LOCAL_InterfaceMethodref_binding
00542                                   .nmordJVM =
00543                                 native_locate_local_method(
00544                                         pcfs,
00545                                         pcpd_Class->name_index,
00546                                         pcpd_NameAndType->name_index,
00547                                         pcpd_NameAndType
00548                                           ->descriptor_index,
00549                                         find_registerNatives);
00550                         }
00551                         else
00552                         {
00553                             atridxFIND =
00554                                 attribute_find_in_method_by_enum(
00555                                     clsidxFIND,
00556                                     mthidxFIND,
00557                                     LOCAL_CODE_ATTRIBUTE);
00558                         }
00559 
00560                         pcpd_InterfaceMethodref
00561                             ->LOCAL_InterfaceMethodref_binding
00562                               .codeatridxJVM =
00563                                   atridxFIND;
00564 
00565                         if (jvm_attribute_index_bad == atridxFIND)
00566                         {
00567                             /* Code not found in method-- fatal error */
00568                             exit_throw_exception(EXIT_JVM_ATTRIBUTE,
00569                                   JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
00570 /*NOTREACHED*/
00571                         }
00572 
00573                         /*
00574                          * Now check if Exceptions attribute is
00575                          * present and store its index.
00576                          */
00577 
00578                         atridxFIND =
00579                             attribute_find_in_method_by_enum(
00580                                 clsidxFIND,
00581                                 mthidxFIND,
00582                                 LOCAL_EXCEPTIONS_ATTRIBUTE);
00583 
00584                         pcpd_InterfaceMethodref
00585                             ->LOCAL_InterfaceMethodref_binding
00586                               .excpatridxJVM =
00587                                   atridxFIND;
00588 
00589                         if (jvm_attribute_index_bad == atridxFIND)
00590                         {
00591                             /* It is OKAY to not have exceptions */
00592                         }
00593 
00594                         /* Add reference unless it references itself */
00595                         if (clsidx != clsidxFIND)
00596                         {
00597                             (rvoid) GC_CLASS_MKREF_FROM_CLASS(
00598                                         clsidx,
00599                                         clsidxFIND);
00600                         }
00601                     }
00602                 }
00603                 break;
00604 
00605             case CONSTANT_String:
00606 
00607             case CONSTANT_Integer:
00608 
00609             case CONSTANT_Float:
00610 
00611             case CONSTANT_Long:
00612 
00613             case CONSTANT_Double:
00614 
00615             case CONSTANT_NameAndType:
00616 
00617             case CONSTANT_Utf8:
00618 
00619                 /*
00620                  * There is no late binding associated
00621                  * directly with these tags.
00622                  */
00623 
00624                 break;
00625 
00626             default:
00627                 GENERIC_FAILURE1_VALUE(rtrue,
00628                                        DMLNORM,
00629                                        "linkage_resolve_class",
00630                                        "Invalid CP tag %d",
00631                                        CP_TAG(pcfs, cpidx),
00632                                        rfalse,
00633                                        rnull,
00634                                        rnull);
00635 
00636         } /* switch ... */
00637 
00638     } /* for (cpidx) */
00639 
00640     /* If this class linked to existing classes, it is fully linked */
00641     if (rtrue == class_fully_linked)
00642     {
00643         CLASS(clsidx).status |= CLASS_STATUS_LINKED;
00644     } 
00645 
00646     cfmsgs_show_constant_pool(CLASS_OBJECT_LINKAGE(clsidx)->pcfs);
00647 
00648     return(class_fully_linked);
00649 
00650 } /* END of linkage_resolve_class() */
00651 
00652 
00653 /*!
00654  * @brief Unresolve class table and object table linkages for a
00655  * class file that is getting ready to be unloaded.
00656  *
00657  *
00658  * @param  clsidx   Class table index to class to unresolve against
00659  *                  all loaded classes.
00660  *
00661  *
00662  * @returns @link #rtrue rtrue@endlink if class linkages were
00663  *          unresolved, @link #rfalse rfalse@endlink otherwise.
00664  *
00665  */
00666 
00667 rboolean linkage_unresolve_class(jvm_class_index clsidx)
00668 {
00669     if (jvm_class_index_null == clsidx)
00670     {
00671         /*
00672          * @link #rtrue rtrue@endlink/@link #rfalse rfalse@endlink
00673          * irrelevant here
00674          */
00675         return(rfalse);
00676     }
00677 
00678     /* If class is not present, cannot unresolve linkages */
00679     if (!(CLASS_STATUS_INUSE & CLASS(clsidx).status))
00680     {
00681         return(rfalse);
00682     }
00683 
00684 
00685     ClassFile *pcfs = CLASS_OBJECT_LINKAGE(clsidx)->pcfs;
00686 
00687     /*
00688      * Scan through constant_pool, resolving any missing items
00689      * that might now be available.
00690      */
00691     jvm_constant_pool_index cpidx;
00692     for (cpidx = CONSTANT_CP_START_INDEX;
00693          cpidx < pcfs->constant_pool_count + CONSTANT_CP_START_INDEX -1;
00694          cpidx++)
00695     {
00696         cp_info_dup *pcpd = pcfs->constant_pool[cpidx];
00697 
00698         CONSTANT_Class_info              *pcpd_Class;
00699         CONSTANT_Fieldref_info           *pcpd_Fieldref;
00700         CONSTANT_Methodref_info          *pcpd_Methodref;
00701         CONSTANT_InterfaceMethodref_info *pcpd_InterfaceMethodref;
00702 
00703         switch (CP_TAG(pcfs, cpidx))
00704         {
00705             case CONSTANT_Class:
00706 
00707                 pcpd_Class = PTR_THIS_CP_Class(pcpd);
00708 
00709                 /* Only unresolve this CP slot if it was resolved */
00710                 if (jvm_class_index_null !=
00711                     pcpd_Class->LOCAL_Class_binding.clsidxJVM)
00712                 {
00713                     /* Remove reference unless it references itself */
00714                     if (clsidx !=
00715                         pcpd_Class->LOCAL_Class_binding.clsidxJVM)
00716                     {
00717                         (rvoid) GC_CLASS_RMREF_FROM_CLASS(
00718                                     clsidx,
00719                                     pcpd_Class
00720                                       ->LOCAL_Class_binding
00721                                         .clsidxJVM);
00722                     }
00723 
00724                     pcpd_Class->LOCAL_Class_binding.clsidxJVM =
00725                         jvm_class_index_null;
00726                 }
00727                 break;
00728 
00729             case CONSTANT_Fieldref:
00730 
00731                 pcpd_Fieldref = PTR_THIS_CP_Fieldref(pcpd);
00732 
00733                 /* Only unresolve this CP slot if it was resolved */
00734                 if (jvm_class_index_null !=
00735                     pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM)
00736                 {
00737                     /* Remove reference unless it references itself */
00738                     if (clsidx != 
00739                         pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM)
00740                     {
00741                         (rvoid) GC_CLASS_RMREF_FROM_CLASS(
00742                                     clsidx,
00743                                     pcpd_Fieldref
00744                                       ->LOCAL_Fieldref_binding
00745                                         .clsidxJVM);
00746                     }
00747 
00748                     pcpd_Fieldref
00749                         ->LOCAL_Fieldref_binding.clsidxJVM =
00750                             jvm_class_index_null;
00751 
00752                     pcpd_Fieldref
00753                         ->LOCAL_Fieldref_binding.fluidxJVM =
00754                             jvm_field_lookup_index_bad;
00755 
00756                     pcpd_Fieldref
00757                         ->LOCAL_Fieldref_binding.oiflagJVM =
00758                             rneither_true_nor_false;
00759 
00760                     pcpd_Fieldref
00761                         ->LOCAL_Fieldref_binding.jvaluetypeJVM =
00762                             LOCAL_BASETYPE_ERROR;
00763                 }
00764                 break;
00765 
00766             case CONSTANT_Methodref:
00767 
00768                 pcpd_Methodref = PTR_THIS_CP_Methodref(pcpd);
00769 
00770                 /* Only unresolve this CP slot if it was resolved */
00771                 if (jvm_class_index_null !=
00772                     pcpd_Methodref->LOCAL_Methodref_binding.clsidxJVM)
00773                 {
00774                     /* Remove reference unless it references itself */
00775                     if (clsidx != 
00776                       pcpd_Methodref->LOCAL_Methodref_binding.clsidxJVM)
00777                     {
00778                         (rvoid) GC_CLASS_RMREF_FROM_CLASS(
00779                                     clsidx,
00780                                     pcpd_Methodref
00781                                       ->LOCAL_Methodref_binding
00782                                         .clsidxJVM);
00783                     }
00784 
00785                     pcpd_Methodref
00786                         ->LOCAL_Methodref_binding.clsidxJVM =
00787                             jvm_class_index_null;
00788 
00789                     pcpd_Methodref
00790                         ->LOCAL_Methodref_binding.mthidxJVM =
00791                             jvm_method_index_bad;
00792 
00793                     pcpd_Methodref
00794                         ->LOCAL_Methodref_binding.codeatridxJVM =
00795                             jvm_attribute_index_bad;
00796 
00797                     pcpd_Methodref
00798                         ->LOCAL_Methodref_binding.excpatridxJVM =
00799                             jvm_attribute_index_bad;
00800 
00801                     pcpd_Methodref
00802                         ->LOCAL_Methodref_binding.nmordJVM =
00803                             jvm_native_method_ordinal_null;
00804                 }
00805                 break;
00806 
00807             case CONSTANT_InterfaceMethodref:
00808 
00809                 pcpd_InterfaceMethodref =
00810                     PTR_THIS_CP_InterfaceMethodref(pcpd);
00811 
00812                 /* Only unresolve this CP slot if it was resolved */
00813                 if (jvm_class_index_null !=
00814                     pcpd_InterfaceMethodref
00815                         ->LOCAL_InterfaceMethodref_binding.clsidxJVM)
00816                 {
00817                     /* Remove reference unless it references itself */
00818                     if (clsidx != 
00819                         pcpd_InterfaceMethodref
00820                           ->LOCAL_InterfaceMethodref_binding.clsidxJVM)
00821                     {
00822                         (rvoid) GC_CLASS_RMREF_FROM_CLASS(
00823                                     clsidx,
00824                                     pcpd_InterfaceMethodref
00825                                       ->LOCAL_InterfaceMethodref_binding
00826                                         .clsidxJVM);
00827                     }
00828 
00829                     pcpd_InterfaceMethodref
00830                         ->LOCAL_InterfaceMethodref_binding.clsidxJVM =
00831                             jvm_class_index_null;
00832 
00833                     pcpd_InterfaceMethodref
00834                         ->LOCAL_InterfaceMethodref_binding.mthidxJVM =
00835                             jvm_method_index_bad;
00836 
00837                     pcpd_InterfaceMethodref
00838                        ->LOCAL_InterfaceMethodref_binding.codeatridxJVM=
00839                             jvm_attribute_index_bad;
00840 
00841                     pcpd_InterfaceMethodref
00842                        ->LOCAL_InterfaceMethodref_binding.excpatridxJVM=
00843                             jvm_attribute_index_bad;
00844 
00845                     pcpd_InterfaceMethodref
00846                        ->LOCAL_InterfaceMethodref_binding.nmordJVM=
00847                             jvm_native_method_ordinal_null;
00848                 }
00849                 break;
00850 
00851             case CONSTANT_String:
00852 
00853             case CONSTANT_Integer:
00854 
00855             case CONSTANT_Float:
00856 
00857             case CONSTANT_Long:
00858 
00859             case CONSTANT_Double:
00860 
00861             case CONSTANT_NameAndType:
00862 
00863             case CONSTANT_Utf8:
00864 
00865                 /*
00866                  * There is no late binding associated
00867                  * directly with these tags.
00868                  */
00869 
00870                 break;
00871 
00872             default:
00873                 GENERIC_FAILURE1_VALUE(rtrue,
00874                                        DMLNORM,
00875                                        "linkage_rmresolve_class",
00876                                        "Invalid CP tag %d",
00877                                        CP_TAG(pcfs, cpidx),
00878                                        rfalse,
00879                                        rnull,
00880                                        rnull);
00881 
00882         } /* switch ... */
00883 
00884     } /* for (cpidx) */
00885 
00886     /* This class is no longer fully linked */
00887     CLASS(clsidx).status &= ~CLASS_STATUS_LINKED;
00888 
00889     return(rtrue);
00890 
00891 } /* END of linkage_unresolve_class() */
00892 
00893 
00894 /* EOF */
00895 

Generated on Fri Sep 30 18:49:05 2005 by  doxygen 1.4.4