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

method.c

Go to the documentation of this file.
00001 /*!
00002  * @file method.c
00003  *
00004  * @brief Manipulate ClassFile methods.
00005  *
00006  *
00007  * @section Control
00008  *
00009  * \$URL: https://svn.apache.org/path/name/method.c $ \$Id: method.c 0 09/28/2005 dlydick $
00010  *
00011  * Copyright 2005 The Apache Software Foundation
00012  * or its licensors, as applicable.
00013  *
00014  * Licensed under the Apache License, Version 2.0 ("the License");
00015  * you may not use this file except in compliance with the License.
00016  * You may obtain a copy of the License at
00017  *
00018  *     http://www.apache.org/licenses/LICENSE-2.0
00019  *
00020  * Unless required by applicable law or agreed to in writing,
00021  * software distributed under the License is distributed on an
00022  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
00023  * either express or implied.
00024  *
00025  * See the License for the specific language governing permissions
00026  * and limitations under the License.
00027  *
00028  * @version \$LastChangedRevision: 0 $
00029  *
00030  * @date \$LastChangedDate: 09/28/2005 $
00031  *
00032  * @author \$LastChangedBy: dlydick $
00033  *         Original code contributed by Daniel Lydick on 09/28/2005.
00034  *
00035  * @section Reference
00036  *
00037  */
00038 
00039 #include "arch.h"
00040 ARCH_COPYRIGHT_APACHE(method, c, "$URL: https://svn.apache.org/path/name/method.c $ $Id: method.c 0 09/28/2005 dlydick $");
00041 
00042 
00043 #include <stdlib.h>
00044 #include <strings.h>
00045 
00046 #include "jvmcfg.h"
00047 #include "cfmacros.h"
00048 #include "classfile.h"
00049 #include "exit.h"
00050 #include "jvm.h"
00051 #include "jvmclass.h"
00052 #include "linkage.h"
00053 #include "nts.h"
00054 #include "utf.h"
00055 
00056 
00057 /*!
00058  * @brief Locate the method_info index for a normal method in a class
00059  * using a constant_pool entry to the name and description of
00060  * the method.
00061  *
00062  *
00063  * @param  clsidx            Class index of class whose method is to be
00064  *                             located.
00065  *
00066  * @param  mthname           UTF8 constant_pool entry of name of method
00067  *                             in class.
00068  *
00069  * @param  mthdesc           UTF8 constant_pool entry of description of
00070  *                             method parameters and return type.
00071  *
00072  *
00073  * @returns method table index of this method in class or
00074  *          @link #jvm_method_index_bad jvm_method_index_bad@endlink
00075  *          if not found.
00076  *
00077  *
00078  * Throws: nothing.  Let caller throw an error like
00079  *         JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR if it is
00080  *         useful at that point.  The purpose of this
00081  *         function is simply to locate the method, not
00082  *         make a value judgment on the meaning of the
00083  *         search result.
00084  *
00085  */
00086 jvm_method_index method_find_by_cp_entry(jvm_class_index  clsidx,
00087                                          cp_info_dup     *mthname,
00088                                          cp_info_dup     *mthdesc)
00089 {
00090     /* Prohibit invalid parameter */
00091     if (jvm_class_index_null == clsidx)
00092     {
00093         exit_throw_exception(EXIT_JVM_METHOD,
00094                              JVMCLASS_JAVA_LANG_INTERNALERROR);
00095     }
00096 
00097     /* Prohibit non-UTF8 CP entries from being parsed */
00098     CONSTANT_Utf8_info *pmthdata = PTR_THIS_CP_Utf8(mthname);
00099     if (CONSTANT_Utf8 != pmthdata->tag)
00100     {
00101         return(jvm_method_index_bad);
00102     }
00103 
00104     pmthdata = PTR_THIS_CP_Utf8(mthdesc);
00105     if (CONSTANT_Utf8 != pmthdata->tag)
00106     {
00107         return(jvm_method_index_bad);
00108     }
00109 
00110     /* Point to class structure, then look for method  */
00111     ClassFile *pcfs = CLASS_OBJECT_LINKAGE(clsidx)->pcfs;
00112 
00113     u2 mcount = pcfs->methods_count;
00114     jvm_method_index mthidx;
00115     for (mthidx = 0; mthidx < mcount; mthidx++)
00116     {
00117         /* Report a match of method name and description when found */
00118         if ((0 == utf_pcfs_strcmp(PTR_THIS_CP_Utf8(mthname),
00119                                   pcfs,
00120                                   pcfs->methods[mthidx]->name_index))
00121             &&
00122             (0 == utf_pcfs_strcmp(PTR_THIS_CP_Utf8(mthdesc),
00123                                   pcfs,
00124                                   pcfs
00125                                     ->methods[mthidx]
00126                                       ->descriptor_index)))
00127         {
00128             return(mthidx);
00129         }
00130     }
00131 
00132     /* Not found */
00133     return(jvm_method_index_bad);
00134 
00135 } /* END of method_find_by_cp_entry() */
00136 
00137 
00138 /*!
00139  * @brief Retrieve by <b><code>(rchar *)</code></b> name a method
00140  * index to a method in a class.
00141  *
00142  *
00143  * @param  clsidx            Class index of class whose method is to be
00144  *                             located.
00145  *
00146  * @param  mthname           Null-terminated string of name of method
00147  *                             in class.
00148  *
00149  * @param  mthdesc           Null-terminated string of description of
00150  *                             method parameters and return type.
00151  *
00152  *
00153  * @returns method index of located method in class, otherwise
00154  *          @link #jvm_method_index_bad jvm_method_index_bad@endlink.
00155  *
00156  */
00157 jvm_method_index
00158     method_find_by_prchar(jvm_class_index  clsidx,
00159                           rchar           *mthname,
00160                           rchar           *mthdesc)
00161 {
00162     cp_info_dup *pcip_mthname = nts_prchar2utf(mthname);
00163     cp_info_dup *pcip_mthdesc = nts_prchar2utf(mthdesc);
00164 
00165     jvm_method_index rc =
00166         method_find_by_cp_entry(clsidx, pcip_mthname, pcip_mthdesc);
00167 
00168     HEAP_FREE_DATA(pcip_mthname);
00169     HEAP_FREE_DATA(pcip_mthdesc);
00170 
00171     return(rc);
00172 
00173 } /* END of method_find_by_prchar() */
00174 
00175 /*!
00176  * @brief Extract method return type from descriptor
00177  *
00178  *
00179  * @param clsidx      Class table index of method to examine.
00180  *
00181  * @param mthdescidx  Class file constant_pool index of method
00182  *                    descriptor to examine.  This entry must be a
00183  *                    CONSTANT_Utf8_info string containing the
00184  *                    descriptor of an unqualified method name.
00185  *
00186  *
00187  * @returns Primative base type of method return value or
00188  *          @link #LOCAL_BASETYPE_ERROR LOCAL_BASETYPE_ERROR@endlink
00189  *          if not found.
00190  *
00191  */
00192 jvm_basetype method_return_type(jvm_class_index         clsidx,
00193                                 jvm_constant_pool_index mthdescidx)
00194 {
00195     cp_info_dup        *pcpd;
00196     CONSTANT_Utf8_info *pcpd_Utf8;
00197 
00198     pcpd =CLASS_OBJECT_LINKAGE(clsidx)->pcfs->constant_pool[mthdescidx];
00199     pcpd_Utf8 = PTR_THIS_CP_Utf8(pcpd);
00200 
00201     u2 idx;
00202            /* Last char will be result:/ - 1/ except 'Lsome/class;' */
00203     for(idx = 0; idx < pcpd_Utf8->length - 1; idx++)
00204     {
00205         /* Scan for parm list closure, next char is return type */
00206         if (METHOD_CHAR_CLOSE_PARM == pcpd_Utf8->bytes[idx])
00207         {
00208             switch (pcpd_Utf8->bytes[idx + 1])
00209             {
00210                 case BASETYPE_CHAR_B:
00211                 case BASETYPE_CHAR_C:
00212                 case BASETYPE_CHAR_D:
00213                 case BASETYPE_CHAR_F:
00214                 case BASETYPE_CHAR_I:
00215                 case BASETYPE_CHAR_J:
00216                 case BASETYPE_CHAR_L:
00217                 case BASETYPE_CHAR_S:
00218                 case BASETYPE_CHAR_Z:
00219                 case BASETYPE_CHAR_ARRAY:
00220                 case METHOD_CHAR_VOID:
00221                     return((jvm_basetype) pcpd_Utf8->bytes[idx + 1]);
00222             }
00223         }
00224     }
00225 
00226     /*!
00227      * @todo  Should this throw a @b VerifyError instead?
00228      *        Is it better to let caller do this?
00229      */
00230 
00231     /* Error, something else found */
00232     return((jvm_basetype) LOCAL_BASETYPE_ERROR);
00233 
00234 } /* END of method_return_type() */
00235 
00236 
00237 /* EOF */
00238 

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