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

cfattrib.c

Go to the documentation of this file.
00001 /*!
00002  * @file cfattrib.c
00003  *
00004  * @brief Implementation of <em>The Java Virtual Machine Specification,
00005  * version 2, Chapter 4, the Class File Format</em>.
00006  *
00007  * This file contains the attribute manipulation functions.  All
00008  * other work is performed in
00009  * @link jvm/src/classfile.c classfile.c@endlink.
00010  *
00011  *
00012  * @section Control
00013  *
00014  * \$URL: https://svn.apache.org/path/name/cfattrib.c $ \$Id: cfattrib.c 0 09/28/2005 dlydick $
00015  *
00016  * Copyright 2005 The Apache Software Foundation
00017  * or its licensors, as applicable.
00018  *
00019  * Licensed under the Apache License, Version 2.0 ("the License");
00020  * you may not use this file except in compliance with the License.
00021  * You may obtain a copy of the License at
00022  *
00023  *     http://www.apache.org/licenses/LICENSE-2.0
00024  *
00025  * Unless required by applicable law or agreed to in writing,
00026  * software distributed under the License is distributed on an
00027  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
00028  * either express or implied.
00029  *
00030  * See the License for the specific language governing permissions
00031  * and limitations under the License.
00032  *
00033  * @version \$LastChangedRevision: 0 $
00034  *
00035  * @date \$LastChangedDate: 09/28/2005 $
00036  *
00037  * @author \$LastChangedBy: dlydick $
00038  *         Original code contributed by Daniel Lydick on 09/28/2005.
00039  *
00040  * @section Reference
00041  *
00042  */
00043 
00044 #include "arch.h"
00045 ARCH_COPYRIGHT_APACHE(cfattrib, c, "$URL: https://svn.apache.org/path/name/cfattrib.c $ $Id: cfattrib.c 0 09/28/2005 dlydick $");
00046 
00047 
00048 #include <string.h>
00049 
00050 #include "jvmcfg.h"
00051 #include "cfmacros.h"
00052 #include "classfile.h"
00053 #include "util.h"
00054 #include "utf.h"
00055 
00056 
00057 /*!
00058  * @brief Convenient shorthand for attribute string comparison
00059  *
00060  *
00061  * @param string  Attribute string for comparison against ClassFile
00062  *                attribute_info value.
00063  *
00064  *
00065  * @returns integer from utf_prchar_pcfs_strcmp()
00066  *
00067  */
00068 #define CMP_ATTRIBUTE(string) \
00069     utf_prchar_pcfs_strcmp(string, pcfs, attribute_name_index)
00070 
00071 
00072 /*!
00073  * @name Attribute test utilities.
00074  *
00075  *
00076  * @param  pcfs                  ClassFile structure containing
00077  *                               attribute @b xxx.
00078  *
00079  * @param  attribute_name_index  Constant pool index of @b xxx
00080  *                               attribute in this class file structure.
00081  *
00082  * @todo Both in this group of functions and probably numerous places
00083  *       around the code, the @link #u2 u2@endlink parameters that
00084  *       reference constant_pool entries should be changed to
00085  *       become type @link #jvm_constant_pool_index
00086          jvm_constant_pool_index@endlink instead as a more accurate
00087  *       reflection of their purpose.  This type was a later addition
00088  *       to the code and is therefore not reflected in the earlier
00089  *       portions that were written.
00090  *
00091  */
00092 
00093 
00094 /*@{ */ /* Begin grouped definitions */
00095 
00096 /*!
00097  * @brief Map UTF8 string names for attributes in a constant_pool
00098  * to LOCAL_xxx_ATTRIBUTE constants for the purpose of switch(int)
00099  * instead of switch("string") code constructions.
00100  *
00101  *
00102  * @returns enumeration constant from classfile_attribute_enum
00103  *
00104  */
00105 
00106 classfile_attribute_enum cfattrib_atr2enum(ClassFile *pcfs,
00107                                            u2      attribute_name_index)
00108 {
00109     if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_CONSTANTVALUE_ATTRIBUTE))
00110     {
00111         return(LOCAL_CONSTANTVALUE_ATTRIBUTE);
00112     }
00113     else
00114     if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_CODE_ATTRIBUTE))
00115     {
00116         return(LOCAL_CODE_ATTRIBUTE);
00117     }
00118     else
00119     if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_EXCEPTIONS_ATTRIBUTE))
00120     {
00121         return(LOCAL_EXCEPTIONS_ATTRIBUTE);
00122     }
00123     else
00124     if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_INNERCLASSES_ATTRIBUTE))
00125     {
00126         return(LOCAL_INNERCLASSES_ATTRIBUTE);
00127     }
00128     else
00129     if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_ENCLOSINGMETHOD_ATTRIBUTE))
00130     {
00131         return(LOCAL_ENCLOSINGMETHOD_ATTRIBUTE);
00132     }
00133     else
00134     if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_SIGNATURE_ATTRIBUTE))
00135     {
00136         return(LOCAL_SIGNATURE_ATTRIBUTE);
00137     }
00138     else
00139     if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_SYNTHETIC_ATTRIBUTE))
00140     {
00141         return(LOCAL_SYNTHETIC_ATTRIBUTE);
00142     }
00143     else
00144     if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_SOURCEFILE_ATTRIBUTE))
00145     {
00146         return(LOCAL_SOURCEFILE_ATTRIBUTE);
00147     }
00148     else
00149     if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_LINENUMBERTABLE_ATTRIBUTE))
00150     {
00151         return(LOCAL_LINENUMBERTABLE_ATTRIBUTE);
00152     }
00153     else
00154     if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_LOCALVARIABLETABLE_ATTRIBUTE))
00155     {
00156         return(LOCAL_LOCALVARIABLETABLE_ATTRIBUTE);
00157     }
00158     else
00159     if (0 ==
00160           CMP_ATTRIBUTE(CONSTANT_UTF8_LOCALVARIABLETYPETABLE_ATTRIBUTE))
00161     {
00162         return(LOCAL_LOCALVARIABLETYPETABLE_ATTRIBUTE);
00163     }
00164     else
00165     if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_DEPRECATED_ATTRIBUTE))
00166     {
00167         return(LOCAL_DEPRECATED_ATTRIBUTE);
00168     }
00169     else
00170     if (0 == CMP_ATTRIBUTE(
00171                      CONSTANT_UTF8_RUNTIMEVISIBLEANNOTATIONS_ATTRIBUTE))
00172     {
00173         return(LOCAL_RUNTIMEVISIBLEANNOTATIONS_ATTRIBUTE);
00174     }
00175     else
00176     if (0 == CMP_ATTRIBUTE(
00177                    CONSTANT_UTF8_RUNTIMEINVISIBLEANNOTATIONS_ATTRIBUTE))
00178     {
00179         return(LOCAL_RUNTIMEINVISIBLEANNOTATIONS_ATTRIBUTE);
00180     }
00181     else
00182     if (0 == CMP_ATTRIBUTE(
00183             CONSTANT_UTF8_RUNTIMEVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE))
00184     {
00185         return(LOCAL_RUNTIMEVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE);
00186     }
00187     else
00188     if (0 == CMP_ATTRIBUTE(
00189           CONSTANT_UTF8_RUNTIMEINVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE))
00190     {
00191       return(LOCAL_RUNTIMEINVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE);
00192     }
00193     else
00194     if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_ANNOTATIONDEFAULT_ATTRIBUTE))
00195     {
00196         return(LOCAL_ANNOTATIONDEFAULT_ATTRIBUTE);
00197     }
00198     else
00199     {
00200         return(LOCAL_UNKNOWN_ATTRIBUTE);
00201     }
00202 
00203 } /* END of cfattrib_atr2enum() */
00204 
00205 
00206 /*!
00207  * @brief Short version of cfattrib_atr2enum(), but only check
00208  * if an index refers to a Code_attribute area.
00209  *
00210  *
00211  * @returns @link #rtrue rtrue@endlink if this attribute is indeed
00212  *          a @link #CONSTANT_UTF8_CODE_ATTRIBUTE
00213             CONSTANT_UTF8_CODE_ATTRIBUTE@endlink,
00214  *          otherwise @link #rfalse rfalse@endlink.
00215  *
00216  */
00217 rboolean cfattrib_iscodeattribute(ClassFile *pcfs,
00218                                   u2 attribute_name_index)
00219 {
00220     if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_CODE_ATTRIBUTE))
00221     {
00222         return(rtrue);
00223     }
00224     else
00225     {
00226         return(rfalse);
00227     }
00228 } /* END of cfattrib_iscodeattribute() */
00229 
00230 /*@} */ /* End of grouped definitions */
00231 
00232 
00233 /*!
00234  * @name Code_attribute deferencing support.
00235  *
00236  */
00237 
00238 /*@{ */ /* Begin grouped definitions */
00239 
00240 /*!
00241  * @brief Conveniently reference the Code_attribute contained in
00242  * an indirect <b><code>attribute_info_dup **dst</code></b>.
00243  *
00244  * After putting in the 4-byte access alignment changes,
00245  * it became obvious that what was once (*dst)->member
00246  * had become quite cumbersome.  Therefore, in order to
00247  * simplify access through (attribute_info_dup *)->ai.member
00248  * constructions, including appropriate casting, the following
00249  * macro is offered to take care of the most common usage.
00250  * The few other references are unchanged, and the code is
00251  * easier to understand.
00252  *
00253  * Notice that @link #DST_AI() DST_AI()@endlink references
00254  * a <b><code>attribute_info_dup *dst</code></b>, while this
00255  * macro references a <b><code>attribute_info_dup **dst</code></b>.
00256  */
00257 #define PTR_DST_AI(dst) ((Code_attribute *) &(*dst)->ai)
00258 
00259 /*!
00260  * @brief Conveniently reference the Code_attribute contained in
00261  * a <b><code>attribute_info_dup *dst</code></b>, namely, with less
00262  * pointer indirection.
00263  *
00264  * This is a counterpart for cfattrib_unloadattribute() where
00265  * no indirection is needed.  Notice that
00266  * @link #PTR_DST_AI() PTR_DST_AI()@endlink references
00267  * a <b><code>attribute_info_dup **dst</code></b>, while this
00268  * macro references a <b><code>attribute_info_dup *dst</code></b>.
00269  *
00270  */
00271 #define     DST_AI(dst) ((Code_attribute *) &dst->ai)
00272 
00273 /*@} */ /* End of grouped definitions */
00274 
00275 
00276 /*!
00277  * @brief Load an attribute and verify that it has either valid contents
00278  * or is ignored as an unknown attribute.
00279  *
00280  * If the attribute index is valid at all (for either a known or even
00281  * an unknown but properly formed attribute), it will be copied
00282  * into its destination area.
00283  *
00284  * @param  pcfs      Pointer to (partially) parsed ClassFile area
00285  *
00286  * @param  dst       Pointer to a attribute_info_dup[] address telling
00287  *                   where in the heap this attribute will be
00288  *                   copied from the source area.
00289  *
00290  * @param  src       Pointer to an attribute in class file image.
00291  *                   This data will be stored in the heap at
00292  *                   location @c @b *dst .
00293  *
00294  *
00295  * @returns Point to first byte past this attribute,
00296  *          or @link #rnull rnull@endlink if parsing problem.
00297  *          If there is a problem, @b dst will contain a valid
00298  *          heap pointer only if there is a valid
00299  *          @link attribute_info.attribute_name_index
00300             attribute_name_index@endlink, else it will also
00301  *          be @link #rnull rnull@endlink.
00302  */
00303 
00304 u1 *cfattrib_loadattribute(ClassFile           *pcfs,
00305                            attribute_info_dup **dst,
00306                            attribute_info      *src)
00307 {
00308     attribute_info tmpatr;
00309     u4             tmplen;
00310 
00311     jbyte *pnext_src = (jbyte *) src;
00312 
00313     tmpatr.attribute_name_index = GETRS2(&src->attribute_name_index);
00314     tmpatr.attribute_length     = GETRI4(&src->attribute_length);
00315 
00316     MACHINE_JSHORT_SWAP(tmpatr.attribute_name_index);
00317     MACHINE_JINT_SWAP(tmpatr.attribute_length);
00318 
00319     cfmsgs_typemsg("cfattrib_loadattribute",
00320                    pcfs,
00321                    tmpatr.attribute_name_index);
00322     sysDbgMsg(DMLNORM,
00323               "cfattrib_loadattribute",
00324               "len=%d",
00325               tmpatr.attribute_length);
00326 
00327     /* Range check the name index (index is unsigned, so not checked) */
00328     GENERIC_FAILURE_PTR(( /* (tmpatr.attribute_name_index <  0) || */
00329                              (tmpatr.attribute_name_index >=
00330                               pcfs->constant_pool_count)),
00331                         DMLNORM,
00332                         "loadClassFileStructures",
00333                         "attribute name index",
00334                         u1,
00335                         rnull,
00336                         rnull);
00337  
00338     /* Calculate total size of this (attribute_info) area in src */
00339     tmplen = sizeof(attribute_info)
00340              - sizeof(u1)
00341              + tmpatr.attribute_length;
00342 
00343     /*
00344      * Skip past this item's header and contents to next attribute,
00345      * adjusting for dummy [info] field.
00346      */
00347     pnext_src += tmplen;
00348 
00349 
00350     /* Calculate total size of this (attribute_info_dup) area in dst */
00351     tmplen = sizeof(attribute_info_dup)
00352              - sizeof(u1)
00353              + tmpatr.attribute_length;
00354 
00355     /* Allocate a heap location to store this attribute */
00356     *dst = (attribute_info_dup *) HEAP_GET_METHOD(tmplen, rfalse);
00357 
00358     /*
00359      * Copy attribute data to heap.  The @b info item is optional,
00360      * depending on which attribute this is.  Copy it in directly
00361      * unless it is a Code_attribute, then do that specially.
00362      * All other variable-length attributes have the @b SINGLE
00363      * variable-length item at the END of the structure (except
00364      * annotatons and local variable type attributes, which are being
00365      * ignored by this implementation);  therefore, there is no need
00366      * to play pointer games to adjust what is stored where in those
00367      * attributes. Simply index that array[] item.
00368      *
00369      * Also investigate attribute type constraints using a
00370      * string-based @c @b switch .
00371      */
00372     (*dst)->empty[0] = FILL_INFO_DUP0;
00373     (*dst)->empty[1] = FILL_INFO_DUP1;
00374     (*dst)->ai.attribute_name_index = tmpatr.attribute_name_index;
00375     (*dst)->ai.attribute_length = tmpatr.attribute_length;
00376 
00377     classfile_attribute_enum atrenum =
00378         cfattrib_atr2enum(pcfs, (*dst)->ai.attribute_name_index);
00379 
00380     if (LOCAL_CODE_ATTRIBUTE == atrenum)
00381     {
00382         /*
00383          * Copy Code_attribute field-by-field as in the top-level
00384          * structure, allocating array[] pieces in that same manner.
00385          *
00386          * Note:  You can get away with referencing
00387          *        @c @b src->member here because these first
00388          *        few members are of fixed length.  You @e still must
00389          *        use GETRS2() or GETRI4() because they are in a
00390          *        byte-stream class file, which has no guaranteed
00391          *        word alignment.
00392          */
00393         PTR_DST_AI(dst)->max_stack =
00394             GETRS2(&((Code_attribute *) src)->max_stack);
00395 
00396         PTR_DST_AI(dst)->max_locals =
00397             GETRS2(&((Code_attribute *) src)->max_locals);
00398 
00399         PTR_DST_AI(dst)->code_length =
00400             GETRI4(&((Code_attribute *) src)->code_length);
00401 
00402         MACHINE_JSHORT_SWAP(*PTR_DST_AI(dst)->max_stack);
00403         MACHINE_JSHORT_SWAP(*PTR_DST_AI(dst)->max_locals);
00404         MACHINE_JINT_SWAP(*PTR_DST_AI(dst)->code_length);
00405 
00406         if (0 == PTR_DST_AI(dst)->code_length)
00407         {
00408             /*
00409              * Possible, but not theoretically reasonable,
00410              * thus prohibited by spec
00411              */
00412             PTR_DST_AI(dst)->code = (u1 *) rnull;
00413         }
00414         else
00415         {
00416             PTR_DST_AI(dst)->code =
00417                 HEAP_GET_METHOD(PTR_DST_AI(dst)->code_length *
00418                                     sizeof(u1),
00419                                 rfalse);
00420 
00421             /* Notice this is copy TO *ptr and FROM *bfr, not *ptr! */
00422             memcpy( PTR_DST_AI(dst)->code,
00423                    /* 1st var len fld in class file code area */
00424                    &((Code_attribute *)  src)->code,
00425                    (PTR_DST_AI(dst)->code_length) * sizeof(u1));
00426 
00427         }
00428 
00429         /*
00430          * Load up variable fields now, use same technique as
00431          * elsewhere.
00432          *
00433          */
00434         jbyte *pabytes =(jbyte *) &((Code_attribute *) src)->code;
00435         pabytes += PTR_DST_AI(dst)->code_length * sizeof(u1);
00436 
00437         u2 *pu2;
00438         MAKE_PU2(pu2, pabytes);
00439 
00440         PTR_DST_AI(dst)->exception_table_length=GETRS2(pu2++);
00441 
00442         pabytes = (u1 *) pu2;
00443 
00444         if (0 == PTR_DST_AI(dst)->exception_table_length)
00445         {
00446             /* Possible, and theoretically reasonable */
00447             PTR_DST_AI(dst)->exception_table = (rvoid *) rnull;
00448         }
00449         else
00450         {
00451             PTR_DST_AI(dst)->exception_table =
00452               HEAP_GET_METHOD(PTR_DST_AI(dst)->exception_table_length *
00453                                   sizeof(exception_table_entry),
00454                               rfalse);
00455 
00456             memcpy(&PTR_DST_AI(dst)->exception_table,
00457                    pabytes,
00458                    (PTR_DST_AI(dst)->exception_table_length) *
00459                        sizeof(exception_table_entry));
00460 
00461             pabytes += (PTR_DST_AI(dst)->exception_table_length) *
00462                              sizeof(exception_table_entry);
00463         }
00464 
00465         MAKE_PU2(pu2, pabytes);
00466 
00467         PTR_DST_AI(dst)->attributes_count = GETRS2(pu2++);
00468 
00469         pabytes = (jbyte *) pu2;
00470 
00471         if (0 == PTR_DST_AI(dst)->attributes_count)
00472         {
00473             PTR_DST_AI(dst)->attributes =
00474                 (attribute_info_dup **) rnull;
00475         }
00476         else
00477         {
00478             PTR_DST_AI(dst)->attributes =
00479                 HEAP_GET_METHOD(PTR_DST_AI(dst)->attributes_count *
00480                                     sizeof(attribute_info_dup *),
00481                                 rtrue);
00482 
00483 
00484             /*
00485              * WARNING!  RECURSIVE CALL:
00486              *
00487              * Load up each attribute in this attribute area.
00488              * This should NOT recurse more than once since there
00489              * can ONLY be ONE Code_attribute per method.
00490              */
00491 
00492             jvm_attribute_index atridx;
00493 
00494             for (atridx = 0;
00495                  atridx < PTR_DST_AI(dst)->attributes_count;
00496                  atridx++)
00497             {
00498                 /*
00499                  * Load an attribute and verify that it is either
00500                  * a valid (or an ignored) attribute, then point to
00501                  * next attribute in class file image.
00502                  */
00503 
00504                 pabytes =
00505                     cfattrib_loadattribute(
00506                         pcfs,
00507                         (attribute_info_dup **)
00508                             &(PTR_DST_AI(dst)->attributes)[atridx],
00509                         (attribute_info *) pabytes);
00510 
00511                 LOAD_SYSCALL_FAILURE_ATTRIB((rnull == pabytes),
00512                                             "load field attribute",
00513                                            *dst,
00514                                            PTR_DST_AI(dst)->attributes);
00515 
00516             } /* for (atridx) */
00517         }
00518 
00519     } /* if LOCAL_CODE_ATTRIBUTE */
00520     else
00521     {
00522         /*
00523          * See comments at top of @c @b if statment as to why
00524          * all other structures can be directly copied into the heap
00525          * area. The only other variable-length attributes are the
00526          * annotation and local variable type attributes, which
00527          * are being ignored by this implementation.
00528          */
00529         if (0 != tmpatr.attribute_length)
00530         {
00531             memcpy(&(*dst)->ai.info,
00532                    &src->info,
00533                    tmpatr.attribute_length);
00534         }
00535 
00536     } /* if LOCAL_CODE_ATTRIBUTE else */
00537 
00538 
00539     /*! @todo Delete this when TODO: items below satisfied */
00540     rboolean dummy = rtrue;
00541 
00542     switch(atrenum)
00543     {
00544         case LOCAL_CONSTANTVALUE_ATTRIBUTE:
00545 
00546             /*! @todo Verify "ConstantValue" attribute contents */
00547             dummy = rfalse;
00548 
00549             break;
00550 
00551         case LOCAL_CODE_ATTRIBUTE:
00552 
00553             /*! @todo Verify "Code" attribute contents */
00554             dummy = rfalse;
00555 
00556             break;
00557 
00558         case LOCAL_EXCEPTIONS_ATTRIBUTE:
00559 
00560             /*! @todo Verify "Exceptions" attribute contents */
00561             dummy = rfalse;
00562 
00563             break;
00564 
00565         case LOCAL_INNERCLASSES_ATTRIBUTE:
00566 
00567             /*! @todo Verify "InnerClasses" attribute contents */
00568             dummy = rfalse;
00569 
00570             break;
00571 
00572         case LOCAL_ENCLOSINGMETHOD_ATTRIBUTE:
00573 
00574            /*! @todo "EnclosingMethod" attribute has nothing to verify*/
00575             dummy = rfalse;
00576 
00577             break;
00578 
00579         case LOCAL_SIGNATURE_ATTRIBUTE:
00580 
00581             /*! @todo "Signature" attribute has nothing to verify */
00582             dummy = rfalse;
00583 
00584             break;
00585 
00586         case LOCAL_SYNTHETIC_ATTRIBUTE:
00587 
00588             /*! @todo "Synthetic" attribute has nothing to verify */
00589             dummy = rfalse;
00590 
00591             break;
00592 
00593         case LOCAL_SOURCEFILE_ATTRIBUTE:
00594 
00595             /*! @todo Verify "SourceFile" attribute contents */
00596             dummy = rfalse;
00597 
00598             break;
00599 
00600         case LOCAL_LINENUMBERTABLE_ATTRIBUTE:
00601 
00602             /*! @todo Verify "LineNumberTable" attribute contents */
00603             dummy = rfalse;
00604 
00605             break;
00606 
00607         case LOCAL_LOCALVARIABLETABLE_ATTRIBUTE:
00608 
00609             /*! @todo Verify "LocalVariableTable" attribute contents */
00610             dummy = rfalse;
00611 
00612             break;
00613 
00614         case LOCAL_LOCALVARIABLETYPETABLE_ATTRIBUTE:
00615 
00616             /*! @todo Verify "LocalVariableTypeTable" attribute
00617                      contents */
00618             dummy = rfalse;
00619 
00620             break;
00621 
00622         case LOCAL_DEPRECATED_ATTRIBUTE:
00623 
00624             /*! @todo "Deprecated" attribute has nothing to verify */
00625             dummy = rfalse;
00626 
00627             break;
00628 
00629         case LOCAL_RUNTIMEVISIBLEANNOTATIONS_ATTRIBUTE:
00630 
00631             /*! @todo Verify "RuntimeVisibleAnnotations" attribute
00632                       contents */
00633             dummy = rfalse;
00634 
00635             break;
00636 
00637         case LOCAL_RUNTIMEINVISIBLEANNOTATIONS_ATTRIBUTE:
00638 
00639             /*! @todo Verify "RuntimeInvisibleAnnotations" attribute
00640                       contents */
00641             dummy = rfalse;
00642 
00643             break;
00644 
00645         case LOCAL_RUNTIMEVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE:
00646 
00647             /*! @todo Verify "RuntimeVisibleParameterAnnotations"
00648                       contents */
00649             dummy = rfalse;
00650 
00651             break;
00652 
00653         case LOCAL_RUNTIMEINVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE:
00654 
00655             /*! @todo Verify "RuntimeInvisibleParameterAnnotations"
00656                       contents */
00657             dummy = rfalse;
00658 
00659             break;
00660 
00661         case LOCAL_ANNOTATIONDEFAULT_ATTRIBUTE:
00662 
00663             /*! @todo "AnnotationDefault" attribute has nothing to 
00664                       verify */
00665             dummy = rfalse;
00666 
00667             break;
00668 
00669         case LOCAL_UNKNOWN_ATTRIBUTE:
00670         default:
00671 
00672             /*!
00673              * @todo Ignore unrecognized attribute.
00674              *       There really should not be anything
00675              *       to do here since the return value
00676              *       already points to the next attribute.
00677              */
00678             dummy = rfalse;
00679 
00680     } /* switch(atrenum) */
00681 
00682     return(pnext_src);
00683 
00684 } /* END of cfattrib_loadattribute() */
00685 
00686 
00687 /*!
00688  * @brief UnLoad an attribute and free its heap area.
00689  *
00690  * @param  pcfs      Pointer to (partially) parsed ClassFile area
00691  *
00692  * @param  dst       Pointer to a attribute_info_dup allocation
00693  *                   where this attribute is stored in the heap
00694  *
00695  * @returns @link #rvoid rvoid@endlink Whether it succeeds or fails,
00696  *          returning anything does not make much sense.  This is
00697  *          similar to @c @b free(3) not returning anything even when
00698  *          a bad pointer was passed in.
00699  *
00700  */
00701 
00702 rvoid cfattrib_unloadattribute(ClassFile  *pcfs,
00703                                attribute_info_dup *dst)
00704 {
00705     /* Ignore any NULL pointers, nothing to do (should NEVER happen) */
00706     if ((rnull == pcfs) || (rnull == dst))
00707     {
00708         return;
00709     }
00710 
00711     /*
00712      * Free attribute data from the heap.  The @b info item is optional,
00713      * depending on which attribute this is.  Free it directly
00714      * unless it is a Code_attribute, then do that specially.
00715      * All other variable-length attributes have the SINGLE variable
00716      * length item at the END of the structure (except annotatons and
00717      * local variable type attributes, which are being ignored by this
00718      * implementation);  therefore, there is no need to play pointer
00719      * games to adjust what is stored where in those attributes.
00720      * Simply index that array[] item and free it.
00721      *
00722      * Also investigate attribute type constraints using a
00723      * string-based @c @b switch .
00724      */
00725 
00726     if (rtrue == cfattrib_iscodeattribute(pcfs,
00727                                      DST_AI(dst)->attribute_name_index))
00728 
00729     {
00730         /*
00731          * Free Code_attribute, all allocations in reverse order.
00732          * (Should not make any difference, but this is how the
00733          * constant_pool is being freed, so just do it the same
00734          * way, namely, the reverse order in which allocations
00735          * were made.)
00736          */
00737 
00738         if (0 == DST_AI(dst)->attributes_count)
00739         {
00740             /*
00741              * Possible, and theoretically reasonable.
00742              *  Nothing to do here.
00743              */
00744             ;
00745         }
00746         else
00747         {
00748             /*
00749              * WARNING!  RECURSIVE CALL:
00750              *
00751              * Load up each attribute in this attribute area.
00752              * This should NOT recurse more than once since there
00753              * can ONLY be ONE Code_attribute per method.
00754              */
00755             jvm_attribute_index atridx;
00756 
00757             for (atridx = 0;
00758                  atridx < DST_AI(dst)->attributes_count;
00759                  atridx++)
00760             {
00761                 /*
00762                  * Unload an attribute
00763                  */
00764 
00765                 cfattrib_unloadattribute(pcfs,
00766                                        DST_AI(dst)->attributes[atridx]);
00767 
00768             } /* for (atridx) */
00769 
00770             HEAP_FREE_METHOD(DST_AI(dst)->attributes);
00771         }
00772 
00773         if (0 == DST_AI(dst)->exception_table_length)
00774         {
00775             /*
00776              * Possible, and theoretically reasonable.
00777              *  Nothing to do here.
00778              */
00779             ;
00780         }
00781         else
00782         {
00783             HEAP_FREE_METHOD(DST_AI(dst)->exception_table);
00784         }
00785 
00786         if (0 == DST_AI(dst)->code_length)
00787         {
00788             /*
00789              * Possible, but not theoretically reasonable,
00790              * thus prohibited by spec.  Nothing to do here
00791              * since @link Code_attribute#code code@endlink
00792              * pointer is @link #rnull rnull@endlink.
00793              */
00794             ;
00795         }
00796         else
00797         {
00798             HEAP_FREE_METHOD(DST_AI(dst)->code);
00799         }
00800 
00801 
00802         /* Finally, free the main attribute area itself */
00803         HEAP_FREE_METHOD(dst);
00804 
00805     } /* if LOCAL_CODE_ATTRIBUTE */
00806     else
00807     {
00808         /*
00809          * See comments at top of @c @b if statment as to
00810          * why all other structures can be directly freed from the
00811          * heap area. The only other variable-length attributes are
00812          * the annotation and local variable type attributes, which
00813          * are being ignored by this implementation.
00814          */
00815         HEAP_FREE_METHOD(dst);
00816 
00817     } /* if LOCAL_CODE_ATTRIBUTE else */
00818 
00819 
00820     return;
00821 
00822 } /* END of cfattrib_unloadattribute() */
00823 
00824 
00825 /* EOF */
00826 

Generated on Fri Sep 30 18:59:25 2005 by  doxygen 1.4.4