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

native.c

Go to the documentation of this file.
00001 /*!
00002  * @file native.c
00003  *
00004  * @brief Local native method interface between JNI and JVM.
00005  *
00006  * JNI native methods are Java methods that are described in
00007  * Java, but are not implemented in Java <em>per se</em>.  Instead,
00008  * they are implemented in a computer language that is compiled into
00009  * the native machine code of the real computing platform-- hence
00010  * the appellation @e native.  Selected native methods are actually
00011  * part of the source code for the Java Virtual Machine itself, yet
00012  * may be referenced through the JNI interface.  Both types of
00013  * native methods are supported in this implementation of the JVM.
00014  * However, most of the code in this source file is concerned with
00015  * @e local native methods.  There is a single hook in
00016  * @link #native_run_method() native_run_method()@endlink that
00017  * deals with the normal JNI interface, and nothing else is required.
00018  *
00019  * Local native methods are JNI methods that are implemented @e within
00020  * the core of the JVM code since they involve an intimate acquaintance
00021  * with its internal structures.  Since they are implemented in this
00022  * way, there is no need to prepare a full JNI call to reference them.
00023  * At class load time, each of these methods is discovered by @link
00024    native_locate_local_method() native_locate_local_method()@endlink
00025  * to be found in the tables generated by macros in each of the
00026  * @link jvm/include/jlObject.h jlXxxx.h@endlink header files
00027  * and referenced here.  A <em>local native method ordinal number</em>
00028  * is assigned to each one.  At run time, this ordinal number is
00029  * examined by @link #native_run_method() native_run_method()@endlink
00030  * when a native method is invoked by the Java byte code.
00031  * If the ordinal number is @link #JVMCFG_JLOBJECT_NMO_NULL
00032    JVMCFG_JLOBJECT_NMO_NULL@endlink, then JNI interface is invoked
00033  * in the normal manner.  If not, the ordinal is used to select
00034  * which native method implementation is invoked.  Each ordinal number
00035  * is guaranteed to be unique by a combination of compilation checking
00036  * of an @c @b enum value and runtime checking by
00037  * @link #native_verify_ordinal_definition()
00038    native_verify_ordinal_definition()@endlink.  The former checks
00039  * uniqueness within a class at compile time.  The latter checks
00040  * collisions between classes at compile time and checks for undefined
00041  * values at run time.
00042  *
00043  * The Java class @c @b java.lang.Thread is a good example
00044  * to show how to add normal JNI native methods and JNI local native
00045  * methods because of the wide variety of native methods that are
00046  * implemented in the initial version of this JNI implementation.
00047  * (In this case, all of them are local native methods, but this
00048  * class will serve as an example for the general case of a
00049  * normal JNI native method.)
00050  *
00051  * Following is the procedure to add a native method to any class.
00052  * At the end of this procedure, instructions are given for how
00053  * to add a new class with native methods, hypothetically named
00054  * @c @b java.lang.NewClassType.  When file names
00055  * containing the class name string "<b>Thread</b>" are referenced
00056  * in the following example, use the @c @b java.lang.Thread
00057  * equivalent file name and simply substitute the string
00058  * "<b>NewClassType</b>" for it. In fact, copying the
00059  * @c @b java.lang.Thread source file(s) to the new class
00060  * name is a suggested way to start writing for the native method
00061  * requirements of a new class.
00062  *
00063  * Here is how to connect a JNI native method into the JVM:
00064  *
00065  * <ul>
00066  * <li> Add the native method declaration to the Java source file
00067  *      @link jni/src/harmony/generic/0.0/src/java/lang/Thread.java
00068         Thread.java@endlink.  For this discussion, it will be called
00069  *      <b><code>native int xxx(boolean b)</code></b>.
00070  * </li>
00071  * <li> Write the native method implementation
00072  *      <b><code>JNIEXPORT jint JNICALL
00073         java_lang_Thread_xxx(JNIEnv *, jboolean)</code></b>
00074  *      in the corresponding 'C' source file
00075         @link jni/src/harmony/generic/0.0/src/java_lang_Thread.c
00076         java_lang_Thread.c@endlink.
00077  * </li>
00078  * <li> Enter the function prototype into the JNI header file
00079  *      @link jni/src/harmony/generic/0.0/include/java_lang_Thread.h
00080         java_lang_Thread.h@endlink.
00081  * </li>
00082  * </ul>
00083  *
00084  * If this is a @e normal JNI native method, this is the end of the
00085  * matter.  If it is a @e local native method, also add its logic
00086  * to the JVM core code:
00087  *
00088  * <ul>
00089  * <li> Add the implementation of the logic as the function
00090  *      <b><code>rint jlThread_xxx(rboolean b)</code></b> in the JVM
00091  *      core source file
00092  *      @link jvm/src/jlThread.c jlThread.c@endlink.
00093  *      This function will likely also be referenced from within the
00094  *      core code itself without regard to the JNI hooks, but be
00095  *      careful to use @e only those data types in its function
00096  *      prototype that will compile in both the JNI environment
00097  *      @e and in the JVM core environment.  As to the contents of the
00098  *      function, the JNI code never sees that part.  It sees only the
00099  *      prototype definition in @link jvm/include/jlThread.h
00100         jlThread.h@endlink.  (See @link jvm/include/jlObject.h
00101         jlObject.h@endlink for further explanation.)
00102  * </li>
00103  * <li> Select a native method ordinal number for the
00104  *      @link #jlThread_nmo_enum jlThread_nmo_enum@endlink enumeration.
00105  *      It should be the next sequential number at the end of the final
00106  *      enumerator in the current edition of the
00107  *      @link #jlThread_nmo_enum jlThread_nmo_enum@endlink
00108  *      enumeration.  If there is an overlap with a higher enumeration
00109  *      series, the compiler will inform of the conflict.  The name
00110  *      should be directly according to the local native
00111  *      implementation's function name, prefixed in the same manner as
00112  *      the other enumerators as @link #JLTHREAD_NMO_CURRENTTHREAD
00113         JLTHREAD_NMO_xxx@endlink.  Some Java methods may have overloaded
00114  *      names, which will resolve to unique names in the JVM core
00115  *      code, so do @e not use the Java method name.  Instead, use
00116  *      the local native method's JVM core code 'C' function name as
00117  *      the basis for this name.  See for example @link
00118         #JLTHREAD_NMO_JOINTIMED_NANOS
00119         JLTHREAD_NMO_JOINTIMED_NANOS@endlink.
00120  * </li>
00121  * <li> Add the prototype definition to
00122  *      @link jvm/include/jlThread.h jlThread.h@endlink in the
00123  *      same manner and per the above argument type constraint.
00124  *      Again, name it and position it in the same manner as the
00125  *      existing functions as
00126  *      @link #jlThread_currentThread() jlThread_xxx()@endlink.
00127  * </li>
00128  * <li> Add a reference to the enumerator 
00129  *      @link #JLTHREAD_NMO_CURRENTTHREAD JLTHREAD_NMO_xxx@endlink
00130  *      to the end of the list of ordinals for the switch statement
00131  *      fragment for the class in
00132  *      @link #NATIVE_TABLE_JLTHREAD NATIVE_TABLE_JLTHREAD@endlink.
00133  * </li>
00134  * <li> Add an entry for the method at the end of the ordinal
00135  *      definition table @link #NATIVE_TABLE_JLTHREAD_ORDINALS
00136         NATIVE_TABLE_JLTHREAD_ORDINALS@endlink.  The ordinal must
00137  *      match the name @link #JLTHREAD_NMO_CURRENTTHREAD
00138         JLTHREAD_NMO_xxx@endlink entered above.  The method name
00139  *      string must match the name of the Java method name @b xxx in
00140  *      the original Java source file @link
00141         jni/src/harmony/generic/0.0/src/java/lang/Thread.java
00142         Thread.java@endlink described above.  The descriptor must
00143  *      match the descriptor in the JNI source file
00144  *      @link jni/src/harmony/generic/0.0/src/java_lang_Thread.c
00145         java_lang_Thread.c@endlink (and associated header file
00146  *      @link jni/src/harmony/generic/0.0/include/java_lang_Thread.h
00147         java_lang_Thread.h@endlink.)  This association is the basis
00148  *      of mapping the local native methods to their class file
00149  *      references at link time.
00150  * </li>
00151  * <li> Add the local native method ordinal
00152  *      @link #JLTHREAD_NMO_CURRENTTHREAD JLTHREAD_NMO_xxx@endlink to
00153  *      one of the groupings according to its return type.  This will
00154  *      assure that the return value is properly processed.  Study
00155  *      existing code for how to properly pass the runtime parameters
00156  *      from the JVM stack into the local native method.  For each
00157  *      of the return types:
00158  *
00159  *     <ul>
00160  *     <li> for a @link #jvoid jvoid@endlink function return type, add
00161  *          the ordinal number to @link #NATIVE_TABLE_JLTHREAD_JVOID 
00162             NATIVE_TABLE_JLTHREAD_JVOID@endlink.
00163  *     </li>
00164  *     <li> for a @link #jvm_object_hash jobject@endlink function
00165  *          return type, add the ordinal number to
00166  *          @link #NATIVE_TABLE_JLTHREAD_JOBJECT 
00167             NATIVE_TABLE_JLTHREAD_JOBJECT@endlink.
00168  *     </li>
00169  *     <li> for a @link #jbyte jbyte@endlink function return type,
00170             add the ordinal number to @link #NATIVE_TABLE_JLTHREAD_JINT 
00171             NATIVE_TABLE_JLTHREAD_JINT@endlink.
00172  *     </li>
00173  *     <li> for a @link #jboolean jboolean@endlink function return type,
00174  *          add the ordinal number to @link #NATIVE_TABLE_JLTHREAD_JINT 
00175             NATIVE_TABLE_JLTHREAD_JINT@endlink.
00176  *     </li>
00177  *     <li> for a @link #jshort jshort@endlink function return type,
00178  *          add the ordinal number to @link #NATIVE_TABLE_JLTHREAD_JINT 
00179             NATIVE_TABLE_JLTHREAD_JINT@endlink.
00180  *     </li>
00181  *     <li> for a @link #jchar jchar@endlink function return type,
00182  *          add the ordinal number to @link #NATIVE_TABLE_JLTHREAD_JINT 
00183             NATIVE_TABLE_JLTHREAD_JINT@endlink.
00184  *     </li>
00185  *     <li> for a @link #jshort jshort@endlink function return type,
00186  *          add the ordinal number to @link #NATIVE_TABLE_JLTHREAD_JINT 
00187             NATIVE_TABLE_JLTHREAD_JINT@endlink.
00188  *     </li>
00189  *     <li> for a @link #jint jint@endlink function return type,
00190  *          add the ordinal number to @link #NATIVE_TABLE_JLTHREAD_JINT 
00191             NATIVE_TABLE_JLTHREAD_JINT@endlink.
00192  *     </li>
00193  *     <li> for a @link #jfloat jfloat@endlink function return type,
00194  *          add the ordinal number to
00195  *          @link #NATIVE_TABLE_JLTHREAD_JFLOAT 
00196             NATIVE_TABLE_JLTHREAD_JFLOAT@endlink.
00197  *     </li>
00198  *     <li> for a @link #jlong jlong@endlink function return type,
00199  *          add the ordinal number to
00200  *          @link #NATIVE_TABLE_JLTHREAD_JLONG 
00201             NATIVE_TABLE_JLTHREAD_JLONG@endlink.
00202  *     </li>
00203  *     <li> for a @link #jdouble jdouble@endlink function return type,
00204  *          add the ordinal number to
00205  *          @link #NATIVE_TABLE_JLTHREAD_JDOUBLE 
00206             NATIVE_TABLE_JLTHREAD_JDOUBLE@endlink.
00207  *     </li>
00208  *     </ul>
00209  *
00210  * </li>
00211  * <li> Add an reference to
00212         @link #jlThread_currentThread() jlThread_xxx()@endlink
00213  *      into the appropriate function in this present source file
00214  *      according to its return type in a manner similar to the above
00215  *      categorization:
00216  *
00217  *     <ul>
00218  *     <li> for a @link #jvoid jvoid@endlink functions, add the ordinal
00219  *          number to @link #native_run_local_return_jvoid()
00220             native_run_local_return_jvoid()@endlink.
00221  *     </li>
00222  *     <li> for a @link #jvm_object_hash jobject@endlink functions, add
00223  *          the ordinal number to @link
00224             #native_run_local_return_jobject()
00225             native_run_local_return_jobject()@endlink.
00226  *     </li>
00227  *     <li> for a @link #jbyte jbyte@endlink functions, add the ordinal
00228  *          number to @link #native_run_local_return_jint()
00229             native_run_local_return_jint()@endlink.
00230  *     </li>
00231  *     <li> for a @link #jboolean jboolean@endlink functions, add the
00232  *          ordinal number to @link #native_run_local_return_jint()
00233             native_run_local_return_jint()@endlink.
00234  *     </li>
00235  *     <li> for a @link #jshort jshort@endlink functions, add the
00236  *          ordinal number to @link #native_run_local_return_jint()
00237             native_run_local_return_jint()@endlink.
00238  *     </li>
00239  *     <li> for a @link #jchar jchar@endlink functions, add the ordinal
00240  *          number to @link #native_run_local_return_jint()
00241             native_run_local_return_jint()@endlink.
00242  *     </li>
00243  *     <li> for a @link #jshort jshort@endlink functions, add the
00244  *          ordinal number to @link #native_run_local_return_jint()
00245             native_run_local_return_jint()@endlink.
00246  *     </li>
00247  *     <li> for a @link #jint jint@endlink functions, add the ordinal
00248  *          number to @link #native_run_local_return_jint()
00249             native_run_local_return_jint()@endlink.
00250  *     </li>
00251  *     <li> for a @link #jfloat jfloat@endlink functions, add the
00252  *          ordinal number to @link #native_run_local_return_jfloat()
00253             native_run_local_return_jfloat()@endlink.
00254  *     </li>
00255  *     <li> for a @link #jlong jlong@endlink functions, add the ordinal
00256  *          number to @link #native_run_local_return_jlong()
00257             native_run_local_return_jlong()@endlink.
00258  *     </li>
00259  *     <li> for a @link #jdouble jdouble@endlink functions, add the
00260  *          ordinal number to @link #native_run_local_return_jdouble()
00261             native_run_local_return_jdouble()@endlink.
00262  *     </li>
00263  *     </ul>
00264  * </li>
00265  * </ul>
00266  *
00267  * If this is a local native method in an existing class, this completes
00268  * the procedure.  However, if this new native method is part of a
00269  * class that is not yet supported by this present source file, such as
00270  * @c @b java.lang.NewClassType as mentioned at the
00271  * beginning of this narrative, then the remaining steps complete
00272  * the procedure of connecting the local methods to the JVM for the
00273  * new @b NewClassType files once they are written:
00274  * 
00275  * <ul>
00276  * <li> Add the JVM core header file declaration to the header file
00277  *      area.  Be sure to @e also add documentation tags for proper
00278  *      visibility to this documentation suite.
00279  *
00280  * @verbatim
00281             #define JLNEWCLASSTYPE_LOCAL_DEFINED
00282             #include "jlNewClassType.h"
00283 
00284    @endverbatim
00285  * </li>
00286  * <li> Add a reference to NATIVE_TABLE_JLNEWCLASSTYPE
00287         to the case statement in
00288  *      @link #native_verify_ordinal_definition()
00289         native_verify_ordinal_definition()@endlink.
00290  * </li>
00291  * <li> Add the entry,
00292  *
00293  * @verbatim
00294     {JVMCLASS_JAVA_LANG_NEWCLASSTYPE,
00295                                  NATIVE_TABLE_JLNEWCLASSTYPE_ORDINALS },
00296 
00297    @endverbatim
00298  *      to the @link #native_local_method_list
00299         to native_local_method_list[]@endlink table.
00300  * </li>
00301  * <li> Add the following macro references to the appropriate
00302  *      locations in @link #native_run_method()
00303         native_run_method()@endlink, based on return type:
00304  *
00305  *     <ul>
00306  *     <li> @b NATIVE_TABLE_JLNEWCLASSTYPE_JVOID </li>
00307  *     <li> @b NATIVE_TABLE_JLNEWCLASSTYPE_JOBJECT </li>
00308  *     <li> @b NATIVE_TABLE_JLNEWCLASSTYPE_JINT </li>
00309  *     <li> @b NATIVE_TABLE_JLNEWCLASSTYPE_JFLOAT </li>
00310  *     <li> @b NATIVE_TABLE_JLNEWCLASSTYPE_JLONG </li>
00311  *     <li> @b NATIVE_TABLE_JLNEWCLASSTYPE_JDOUBLE </li>
00312  *     </ul>
00313  * </li>
00314  * </ul>
00315  *
00316  * This completes the JNI interconnection process.
00317  *
00318  *
00319  * @section Control
00320  *
00321  * \$URL: https://svn.apache.org/path/name/native.c $ \$Id: native.c 0 09/28/2005 dlydick $
00322  *
00323  * Copyright 2005 The Apache Software Foundation
00324  * or its licensors, as applicable.
00325  *
00326  * Licensed under the Apache License, Version 2.0 ("the License");
00327  * you may not use this file except in compliance with the License.
00328  * You may obtain a copy of the License at
00329  *
00330  *     http://www.apache.org/licenses/LICENSE-2.0
00331  *
00332  * Unless required by applicable law or agreed to in writing,
00333  * software distributed under the License is distributed on an
00334  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
00335  * either express or implied.
00336  *
00337  * See the License for the specific language governing permissions
00338  * and limitations under the License.
00339  *
00340  * @version \$LastChangedRevision: 0 $
00341  *
00342  * @date \$LastChangedDate: 09/28/2005 $
00343  *
00344  * @author \$LastChangedBy: dlydick $
00345  *         Original code contributed by Daniel Lydick on 09/28/2005.
00346  *
00347  * @section Reference
00348  *
00349  */
00350 
00351 #include "arch.h"
00352 ARCH_COPYRIGHT_APACHE(native, c, "$URL: https://svn.apache.org/path/name/native.c $ $Id: native.c 0 09/28/2005 dlydick $");
00353 
00354 #include "jvmcfg.h"
00355 #include "classfile.h"
00356 #include "exit.h"
00357 #include "jvm.h"
00358 #include "jvmclass.h"
00359 #include "method.h"
00360 #include "util.h"
00361 #include "utf.h"
00362 
00363 /* Include ALL local native class header files here: */
00364 
00365 /*!
00366  * @brief Local implementation mode inclusion of
00367  * @link jvm/include/jlObject.h jlObject.h@endlink
00368  */
00369 #define JLOBJECT_LOCAL_DEFINED
00370 #include "jlObject.h"
00371 
00372 /*!
00373  * @brief Local implementation mode inclusion of
00374  * @link jvm/include/jlClass.h jlClass.h@endlink
00375  */
00376 #define JLCLASS_LOCAL_DEFINED
00377 #include "jlClass.h"
00378 
00379 /*!
00380  * @brief Local implementation mode inclusion of
00381  * @link jvm/include/jlString.h jlString.h@endlink
00382  */
00383 #define JLSTRING_LOCAL_DEFINED
00384 #include "jlString.h"
00385 
00386 /*!
00387  * @brief Local implementation mode inclusion of
00388  * @link jvm/include/jlThread.h jlThread.h@endlink
00389  */
00390 #define JLTHREAD_LOCAL_DEFINED
00391 #include "jlThread.h"
00392 
00393 
00394 /*!
00395  * @name Real machine automatic local variable stack frame conversion.
00396  *
00397  * @brief List of real machine local variables used as scratchpad
00398  * for the several @link POP_JINT() POP_xxx()@endlink
00399  * macros that retrieve JVM stack parms for distribution to
00400  * local native methods.  Mix and match in the various functions
00401  * according to which operands are to be parsed.
00402  *
00403  */
00404 
00405 /*@{ */ /* Begin grouped definitions */
00406 
00407 #define POP_SCRATCHPAD_JVM       \
00408     jvm_class_index clsidxCURR;  \
00409     jvm_object_hash objhashTHIS
00410 
00411 #define POP_SCRATCHPAD_JOBJECT \
00412     jint  joparm
00413 
00414 #define POP_SCRATCHPAD_JINT \
00415     jint  jiparm
00416 
00417 #define POP_SCRATCHPAD_JFLOAT \
00418     jint  jfparm
00419 
00420 #define POP_SCRATCHPAD_JLONG \
00421     jlong jlparm;             \
00422     jint  jlpms;              \
00423     jint  jlpls
00424 
00425 #define POP_SCRATCHPAD_JDOUBLE \
00426     jint  jdparm;               \
00427     jint  jlpms;                \
00428     jint  jlpls
00429 
00430 /*@} */ /* End of grouped definitions */
00431 
00432 
00433 /*!
00434  * @name JVM stack frame access for local native method interface.
00435  *
00436  * @brief Map JVM operand stack parameters to real machine
00437  * native method implementation by popping parameters from
00438  * JVM stack into real machine local variables that are then
00439  * passed to local native methods.
00440  *
00441  */
00442 
00443 /*@{ */ /* Begin grouped definitions */
00444 
00445 
00446 /*!
00447  * @brief Retrieve current class index parameter from the top of
00448  * the JVM stack into real machine local variable @b clsidxCURR
00449  * for use as a parameter to local native @c @b static
00450  * method calls.
00451  *
00452  *
00453  * @param thridx  Thead index of stack to access.
00454  *
00455  *
00456  * @returns @link #rvoid rvoid@endlink
00457  *
00458  */
00459 #define GET_CURRENT_CLSIDX(thridx) \
00460     GET_PC_FIELD(thridx, clsidxCURR, clsidx)
00461 
00462 
00463 /*!
00464  * @brief Retrieve @c @b this object hash parameter from the
00465  * top of the JVM stack into real machine local variable @b objhashTHIS
00466  * for use as a parameter to local native object instance method calls.
00467  *
00468  *
00469  * @param thridx  Thead index of stack to access.
00470  *
00471  *
00472  * @returns @link #rvoid rvoid@endlink
00473  *
00474  */
00475 #define POP_THIS_OBJHASH(thridx) \
00476     POP(thridx, objhashTHIS, jvm_object_hash)
00477 
00478 
00479 /*!
00480  * @brief Retrieve a (jobject) method parameter from the top of
00481  * the JVM stack into real machine local variable @b joparm
00482  * for use as a parameter to local native method calls.
00483  *
00484  *
00485  * @param thridx  Thead index of stack to access.
00486  *
00487  *
00488  * @returns @link #rvoid rvoid@endlink
00489  *
00490  */
00491 #define POP_JOBJECT(thridx) \
00492     POP(thridx, joparm, jvm_object_hash)
00493 
00494 
00495 /*!
00496  * @brief Retrieve a (jint) method parameter from the top of
00497  * the JVM stack into real machine local variable @b jiparm
00498  * for use as a parameter to local native method calls.
00499  *
00500  *
00501  * @param thridx  Thead index of stack to access.
00502  *
00503  *
00504  * @returns @link #rvoid rvoid@endlink
00505  *
00506  */
00507 #define POP_JINT(thridx) \
00508     POP(thridx, jiparm, jint)
00509 
00510 
00511 /*!
00512  * @brief Retrieve a (jfloat) method parameter from the top of
00513  * the JVM stack into real machine local variable @b jfparm
00514  * for use as a parameter to local native method calls.
00515  *
00516  *
00517  * @param thridx  Thead index of stack to access.
00518  *
00519  *
00520  * @returns @link #rvoid rvoid@endlink
00521  *
00522  * @todo Perform value set conversion here for native methods
00523  *       and elsewhere for virtual methods.
00524  *
00525  */
00526 #define POP_JFLOAT(thridx) \
00527     POP(thridx, jfparm, jfloat)
00528 
00529 
00530 /*!
00531  * @brief Retrieve a (jlong) method parameter from the top of
00532  * the JVM stack into real machine local variable @b jlparm
00533  * for use as a parameter to local native method calls.
00534  *
00535  *
00536  * @param thridx  Thead index of stack to access.
00537  *
00538  *
00539  * @returns @link #rvoid rvoid@endlink
00540  *
00541  */
00542 #define POP_JLONG(thridx) \
00543     POP(thridx, jlpls, jint); \
00544     POP(thridx, jlpms, jint); \
00545     jlparm = bytegames_combine_jlong(jlpms, jlpls)
00546 
00547 
00548 /*!
00549  * @brief Retrieve a (jdouble) method parameter from the top of
00550  * the JVM stack into real machine local variable @b jdparm
00551  * for use as a parameter to local native method calls.
00552  *
00553  *
00554  * @param thridx  Thead index of stack to access.
00555  *
00556  *
00557  * @returns @link #rvoid rvoid@endlink
00558  *
00559  * @todo Perform value set conversion here for native methods
00560  *       and elsewhere for virtual methods.
00561  *
00562  */
00563 #define POP_JDOUBLE(thridx) \
00564     POP(thridx, jlpls, jint); \
00565     POP(thridx, jlpms, jint); \
00566     jdparm = bytegames_combine_jdouble(jlpms, jlpls)
00567 
00568 /*@} */ /* End of grouped definitions */
00569 
00570 
00571 /*!
00572  * @name Local native method interface.
00573  *
00574  * @brief Map JVM stack frame to real machine native method
00575  * implementation, invoke the actual real function, and
00576  * report the results.
00577  *
00578  *
00579  * @param nmord   Ordinal number definition of local native method.
00580  *
00581  * @param thridx  JVM thread where request came from.
00582  *
00583  *
00584  * @returns @link #rvoid rvoid@endlink
00585  *
00586  */
00587 
00588 /*@{ */ /* Begin grouped definitions */
00589 
00590 /*!
00591  * @brief Local native equivalent of
00592  * <b><code>native void mthname()</code></b>
00593  *
00594  * The JVM returns from a @c @b void method
00595  * using the @b RETURN opcode.
00596  *
00597  */
00598 static
00599     rvoid native_run_local_return_jvoid(jvm_native_method_ordinal nmord,
00600                                         jvm_thread_index         thridx)
00601 {
00602     POP_SCRATCHPAD_JVM;
00603     POP_SCRATCHPAD_JINT;
00604     POP_SCRATCHPAD_JLONG;
00605 
00606     switch((int) nmord)
00607     {
00608         case JLOBJECT_NMO_WAIT4EVER:
00609             POP_THIS_OBJHASH(thridx);
00610 
00611             jlObject_wait4ever(objhashTHIS);
00612             break;
00613 
00614         case JLOBJECT_NMO_WAITTIMED:
00615             POP_JLONG(thridx);
00616             POP_THIS_OBJHASH(thridx);
00617 
00618             jlObject_waittimed(objhashTHIS, jlparm);
00619             break;
00620 
00621         case JLTHREAD_NMO_YIELD:
00622             GET_CURRENT_CLSIDX(thridx);
00623 
00624             jlThread_yield(clsidxCURR);
00625             break;
00626 
00627         case JLTHREAD_NMO_INTERRUPT:
00628             POP_THIS_OBJHASH(thridx);
00629 
00630             jlThread_interrupt(objhashTHIS);
00631             break;
00632 
00633         case JLTHREAD_NMO_JOIN4EVER:
00634             POP_THIS_OBJHASH(thridx);
00635 
00636             jlThread_join4ever(objhashTHIS);
00637             break;
00638 
00639         case JLTHREAD_NMO_JOINTIMED:
00640             POP_JLONG(thridx);
00641             POP_THIS_OBJHASH(thridx);
00642 
00643             jlThread_jointimed(objhashTHIS, jlparm);
00644             break;
00645 
00646         case JLTHREAD_NMO_JOINTIMED_NANOS:
00647             POP_JINT(thridx);
00648             POP_JLONG(thridx);
00649             POP_THIS_OBJHASH(thridx);
00650 
00651             jlThread_jointimed_nanos(objhashTHIS, jlparm, jiparm);
00652             break;
00653 
00654         case JLTHREAD_NMO_SETDAEMON:
00655             POP_JINT(thridx);
00656             POP_THIS_OBJHASH(thridx);
00657 
00658             jlThread_setDaemon(objhashTHIS, (jboolean) jiparm);
00659             break;
00660 
00661         case JLTHREAD_NMO_STOP:
00662             POP_THIS_OBJHASH(thridx);
00663 
00664             jlThread_stop(objhashTHIS);
00665             break;
00666 
00667         case JLTHREAD_NMO_SUSPEND:
00668             POP_THIS_OBJHASH(thridx);
00669 
00670             jlThread_suspend(objhashTHIS);
00671             break;
00672 
00673         case JLTHREAD_NMO_RESUME:
00674             POP_THIS_OBJHASH(thridx);
00675 
00676             jlThread_resume(objhashTHIS);
00677             break;
00678 
00679         /* case JVMCFG_JLOBJECT_NMO_NULL: */
00680         default:
00681             exit_throw_exception(EXIT_JVM_INTERNAL,
00682                                  JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
00683 /*NOTREACHED*/
00684     }
00685 
00686     /* No data to pass back, so just leave */
00687     return;
00688 
00689 } /* END of native_run_local_return_jvoid() */
00690 
00691 
00692 /*!
00693  * @brief Local native equivalent of
00694  * <b><code>native jobject mthname()</code></b>
00695  *
00696  * The JVM returns from a @c @b jobject method
00697  * using the @b ARETURN opcode.
00698  *
00699  */
00700 static jvm_object_hash
00701     native_run_local_return_jobject(jvm_native_method_ordinal nmord,
00702                                     jvm_thread_index         thridx)
00703 {
00704     jvm_object_hash rc;
00705 
00706     POP_SCRATCHPAD_JVM;
00707 
00708     switch(nmord)
00709     {
00710         case JLOBJECT_NMO_GETCLASS:
00711             POP_THIS_OBJHASH(thridx);
00712 
00713             rc = jlObject_getClass(objhashTHIS);
00714             break;
00715 
00716         case JLTHREAD_NMO_CURRENTTHREAD:
00717             GET_CURRENT_CLSIDX(thridx);
00718 
00719             rc = jlThread_currentThread(clsidxCURR);
00720             break;
00721 
00722         case JVMCFG_JLOBJECT_NMO_NULL:
00723         default:
00724             exit_throw_exception(EXIT_JVM_INTERNAL,
00725                                  JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
00726 /*NOTREACHED*/
00727     }
00728 
00729     /* Store result back into JVM stack frame of invoker */
00730     PUSH(thridx, rc);
00731 
00732     /* Also return result to caller */
00733     return(rc);
00734     
00735 } /* END of native_run_local_return_jobject() */
00736 
00737 
00738 /*!
00739  * @brief Local native equivalent of
00740  * <b><code>native int mthname()</code></b>, also used for
00741  * @c @b (boolean), @c @b (byte), @c @b (char),
00742  * and @c @b (short) return types.
00743  *
00744  * The JVM returns from a @c @b int method (and those of
00745  * the listed sub-integer return types) using the @b IRETURN opcode.
00746  *
00747  */
00748 static
00749     jint native_run_local_return_jint(jvm_native_method_ordinal nmord,
00750                                       jvm_thread_index         thridx)
00751 {
00752     jint rc;
00753 
00754     POP_SCRATCHPAD_JVM;
00755     POP_SCRATCHPAD_JOBJECT;
00756     POP_SCRATCHPAD_JINT;
00757     POP_SCRATCHPAD_JLONG;
00758 
00759     switch(nmord)
00760     {
00761         case JLOBJECT_NMO_HASHCODE:
00762             POP_THIS_OBJHASH(thridx);
00763 
00764             rc = jlObject_hashCode(objhashTHIS);
00765             break;
00766 
00767         case JLCLASS_NMO_ISARRAY:
00768             POP_THIS_OBJHASH(thridx);
00769 
00770             rc = jlClass_isArray(objhashTHIS);
00771             break;
00772 
00773         case JLCLASS_NMO_ISPRIMATIVE:
00774             POP_THIS_OBJHASH(thridx);
00775 
00776             rc = jlClass_isPrimative(objhashTHIS);
00777             break;
00778 
00779         case JLTHREAD_NMO_INTERRUPTED:
00780             GET_CURRENT_CLSIDX(thridx);
00781 
00782             rc = jlThread_interrupted(clsidxCURR);
00783             break;
00784 
00785         case JLTHREAD_NMO_ISINTERRUPTED:
00786             POP_THIS_OBJHASH(thridx);
00787 
00788             rc = jlThread_isInterrupted(objhashTHIS);
00789             break;
00790 
00791         case JLTHREAD_NMO_SLEEP:
00792             POP_JLONG(thridx);
00793             GET_CURRENT_CLSIDX(thridx);
00794 
00795             rc = jlThread_sleep(clsidxCURR, jlparm);
00796             break;
00797 
00798         case JLTHREAD_NMO_SLEEP_NANOS:
00799             POP_JINT(thridx);
00800             POP_JLONG(thridx);
00801             GET_CURRENT_CLSIDX(thridx);
00802 
00803             rc = jlThread_sleep_nanos(clsidxCURR, jlparm, jiparm);
00804             break;
00805 
00806         case JLTHREAD_NMO_ISALIVE:
00807             POP_THIS_OBJHASH(thridx);
00808 
00809             rc = (jint) jlThread_isAlive(objhashTHIS);
00810             break;
00811 
00812         case JLTHREAD_NMO_START:
00813             POP_THIS_OBJHASH(thridx);
00814 
00815             rc = (jint) jlThread_start(objhashTHIS);
00816             break;
00817 
00818         case JLTHREAD_NMO_COUNTSTACKFRAMES:
00819             POP_THIS_OBJHASH(thridx);
00820 
00821             rc = jlThread_countStackFrames(objhashTHIS);
00822             break;
00823 
00824         case JLTHREAD_NMO_HOLDSLOCK:
00825             POP_JOBJECT(thridx);
00826             GET_CURRENT_CLSIDX(thridx);
00827 
00828             rc = (jint) jlThread_holdsLock(objhashTHIS, joparm);
00829             break;
00830 
00831         case JLTHREAD_NMO_SETPRIORITY:
00832             POP_JINT(thridx);
00833             POP_THIS_OBJHASH(thridx);
00834 
00835             rc = (jint) 
00836                  jlThread_setPriority(objhashTHIS, jiparm);
00837             break;
00838 
00839         case JLTHREAD_NMO_GETPRIORITY:
00840             POP_THIS_OBJHASH(thridx);
00841 
00842             rc = jlThread_getPriority(objhashTHIS);
00843             break;
00844 
00845         case JLTHREAD_NMO_DESTROY:
00846             POP_THIS_OBJHASH(thridx);
00847 
00848             rc = (jint) jlThread_destroy(objhashTHIS);
00849             break;
00850 
00851         case JLTHREAD_NMO_CHECKACCESS:
00852             POP_THIS_OBJHASH(thridx);
00853 
00854             rc = (jint) jlThread_checkAccess(objhashTHIS);
00855             break;
00856 
00857         case JLTHREAD_NMO_ISDAEMON:
00858             POP_THIS_OBJHASH(thridx);
00859 
00860             rc = (jint) jlThread_isDaemon(objhashTHIS);
00861             break;
00862 
00863         case JVMCFG_JLOBJECT_NMO_NULL:
00864         default:
00865             exit_throw_exception(EXIT_JVM_INTERNAL,
00866                                  JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
00867 /*NOTREACHED*/
00868     }
00869 
00870     /* Store result back into JVM stack frame of invoker */
00871     PUSH(thridx, rc);
00872 
00873     /* Also return result to caller */
00874     return(rc);
00875     
00876 } /* END of native_run_local_return_jint() */
00877 
00878 
00879 /*!
00880  * @brief Local native equivalent of
00881  * <b><code>native float mthname()</code></b>
00882  *
00883  * The JVM returns from a @c @b float method
00884  * using the @b FRETURN opcode.
00885  *
00886  */
00887 static jfloat
00888     native_run_local_return_jfloat(jvm_native_method_ordinal nmord,
00889                                    jvm_thread_index         thridx)
00890 {
00891     jfloat rc;
00892 
00893     /* POP_SCRATCHPAD_JVM; */
00894 
00895     switch(nmord)
00896     {
00897         case JVMCFG_JLOBJECT_NMO_NULL:
00898         default:
00899             exit_throw_exception(EXIT_JVM_INTERNAL,
00900                                  JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
00901 /*NOTREACHED*/
00902     }
00903 
00904     /* Store result back into JVM stack frame of invoker */
00905     PUSH(thridx, rc);
00906 
00907     /* Also return result to caller */
00908     return(rc);
00909 
00910 } /* END of native_run_local_return_jfloat() */
00911 
00912 
00913 /*!
00914  * @brief Local native equivalent of
00915  * <b><code>native long mthname()</code></b>
00916  *
00917  * The JVM returns from a @c @b long method
00918  * using the @b LRETURN opcode.
00919  *
00920  */
00921 static
00922     jlong native_run_local_return_jlong(jvm_native_method_ordinal nmord,
00923                                         jvm_thread_index         thridx)
00924 {
00925     jlong rc;
00926     jint rcms, rcls;
00927 
00928     /* POP_SCRATCHPAD_JVM; */
00929 
00930     switch(nmord)
00931     {
00932         case JVMCFG_JLOBJECT_NMO_NULL:
00933         default:
00934             exit_throw_exception(EXIT_JVM_INTERNAL,
00935                                  JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
00936 /*NOTREACHED*/
00937     }
00938 
00939     /* Store result back into JVM stack frame of invoker */
00940 
00941     bytegames_split_jlong(rc, &rcms, &rcls);
00942 
00943     PUSH(thridx, rcms);
00944     PUSH(thridx, rcls);
00945 
00946     /* Also return result to caller */
00947     return(rc);
00948 
00949 } /* END of native_run_local_return_jlong() */
00950 
00951 
00952 /*!
00953  * @brief Local native equivalent of
00954  * <b><code>native double mthname()</code></b>
00955  *
00956  * The JVM returns from a @c @b double method
00957  * using the @b DRETURN opcode.
00958  *
00959  */
00960 static jdouble
00961     native_run_local_return_jdouble(jvm_native_method_ordinal nmord,
00962                                     jvm_thread_index         thridx)
00963 {
00964     jdouble rc;
00965     jint rcms, rcls;
00966 
00967     /* POP_SCRATCHPAD_JVM */;
00968 
00969     switch(nmord)
00970     {
00971         case JVMCFG_JLOBJECT_NMO_NULL:
00972         default:
00973             exit_throw_exception(EXIT_JVM_INTERNAL,
00974                                  JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
00975 /*NOTREACHED*/
00976     }
00977 
00978     /* Store result back into JVM stack frame of invoker */
00979 
00980     bytegames_split_jdouble(rc, &rcms, &rcls);
00981 
00982     PUSH(thridx, rcms);
00983     PUSH(thridx, rcls);
00984 
00985     /* Also return result to caller */
00986     return(rc);
00987 
00988 } /* END of native_run_local_return_jdouble() */
00989 
00990 /*@} */ /* End of grouped definitions */
00991 
00992 
00993 /*!
00994  * @brief Verify the validity of a native method ordinal number.
00995  *
00996  * The purpose of this function is to verify that @e all of the
00997  * ordinal numbers are listed in the @c @b switch statement
00998  * here and are unique and complete for all defined local native
00999  * methods.
01000  *
01001  * @internal  Although this function is invoked from
01002  * @link #native_locate_local_method()
01003           native_locate_local_method()@endlink, the real purpose
01004  * is fulfilled at compile time by verifying that there is a
01005  * completely unique set of ordinals across all classes.  Invoking
01006  * it at run time adds to this integrity by verifying that a
01007  * native method invocation is using an ordinal that actually exists.
01008  *
01009  *
01010  * @param nmord   Ordinal number definition of local native method.
01011  *
01012  *
01013  * @returns @link #rvoid rvoid@endlink if found, else throws an error.
01014  *
01015  *
01016  * @throws JVMCLASS_JAVA_LANG_INTERNALERROR
01017  *         @link #JVMCLASS_JAVA_LANG_INTERNALERROR
01018  *         if ordinal number of local native method
01019  *         was not found.@endlink.
01020  *
01021  */
01022  
01023 static rvoid native_verify_ordinal_definition(
01024                                         jvm_native_method_ordinal nmord)
01025 {
01026     switch(nmord)
01027     {
01028         /*
01029          * Add @b NATIVE_TABLE_JLxxx entries
01030          * here @b WITHOUT colon (:) characters...
01031          */
01032         NATIVE_TABLE_JLOBJECT
01033         NATIVE_TABLE_JLCLASS
01034         NATIVE_TABLE_JLSTRING
01035         NATIVE_TABLE_JLTHREAD
01036 
01037         /*
01038          * All classes use the same register/unregister ordinals
01039          */
01040         case JVMCFG_JLOBJECT_NMO_REGISTER:
01041         case JVMCFG_JLOBJECT_NMO_UNREGISTER:
01042             return;
01043 
01044         case JVMCFG_JLOBJECT_NMO_NULL:
01045         default:
01046             exit_throw_exception(EXIT_JVM_INTERNAL,
01047                                  JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
01048 /*NOTREACHED*/
01049     }
01050     
01051 } /* END of native_verify_ordinal_definition() */
01052 
01053 
01054 /*!
01055  * @name Native local method mapping structures
01056  */
01057 
01058 /*@{ */ /* Begin grouped definitions */
01059 
01060 /*!
01061  * @brief Number of native_local_method_map slots
01062  * in the largest class with local native methods.
01063  *
01064  * This integer should be increased to accomodate the
01065  * number of Java classes in the table.  Let the
01066  * compiler complains about too many initializers in the
01067  * @link #native_local_method_list native_local_method_list[]@endlink
01068  * array and increase the value so that just the right
01069  * number of array elements are allocated.  (There is
01070  * no point in allocating extra slots because they
01071  * will sit empty and unused.)
01072  *
01073  */
01074 #define NLML_MAX_CLASSES 5
01075 
01076 
01077 /*!
01078  * @brief Number of native_local_method_ordinal_map slots
01079  * in the largest class with local native methods.
01080  *
01081  * This integer should be increased to accomodate the maximum class.
01082  * Let the compiler complains about too many initializers in
01083  * @link #native_local_method_map.nlmo_map
01084  * native_local_method_list.nlmo_map@endlink and then increase
01085  * the value so that just the right number of elements are
01086  * allocated for the largest class.
01087  *
01088  */
01089 #define NLMO_MAX_SLOTS 25
01090 
01091 
01092 /*!
01093  * @brief Associate a local native method ordinal number
01094  * with its JVM method name and description string.
01095  *
01096  * This table gathers all of the @link #NATIVE_TABLE_JLOBJECT_ORDINALS
01097    NATIVE_TABLE_JLxxxxxx_ORDINALS@endlink definitions from the
01098  * @link jvm/src/jlObject.c jlXxxxx.c@endlink JNI local method
01099  * interface source files for reference in this code.
01100  */
01101 
01102 typedef struct
01103 {
01104                      /*! Ordinal number for this method */
01105     jvm_native_method_ordinal nmord;
01106 
01107                      /*! Null-terminated string name of method */
01108     rchar *mthname;
01109 
01110                      /*! Null-terminated string description of method */
01111     rchar *mthdesc;
01112 
01113 } native_local_method_ordinal_map;
01114 
01115 
01116 /*!
01117  * @brief Associate a class name with its local native method
01118  * ordinal numbers and its JVM method name and description
01119  * strings.
01120  *
01121  * This table gathers all of the @link #NATIVE_TABLE_JLOBJECT_ORDINALS
01122    NATIVE_TABLE_JLxxxxxx_ORDINALS@endlink definitions from the
01123  * @link jvm/src/jlObject.c jlXxxxx.c@endlink JNI local method
01124  * interface source files for reference in this code.
01125  */
01126 typedef struct
01127 {
01128                            /*! Null-terminated class name string */
01129     rchar *clsname;
01130 
01131                            /*! Associate this class with a list of
01132                                local native methods that are implemented
01133                                in this class */
01134 
01135     native_local_method_ordinal_map nlmo_map[NLMO_MAX_SLOTS];
01136 
01137 } native_local_method_map;
01138 
01139 
01140 /*!
01141  * @brief Complete and authoritative list of Java classes implementing
01142  * local native methods.  Each @link jvm/include/jlObject.h
01143    jlXxxxx.h@endlink header file defines a suite of
01144  * @link #NATIVE_TABLE_JLOBJECT_ORDINALS
01145    NATIVE_TABLE_JLxxxxx_ORDINALS@endlink.  This suite is entered
01146  * here for processing by the local native method logic.
01147  *
01148  * @see jvm/include/jlClass.h
01149  *
01150  * @see jvm/include/jlObject.h
01151  *
01152  * @see jvm/include/jlString.h
01153  *
01154  * @see jvm/include/jlThread.h
01155  *
01156  */
01157 native_local_method_map native_local_method_list[NLML_MAX_CLASSES] =
01158 {
01159     {JVMCLASS_JAVA_LANG_OBJECT, NATIVE_TABLE_JLOBJECT_ORDINALS },
01160     {JVMCLASS_JAVA_LANG_CLASS,  NATIVE_TABLE_JLCLASS_ORDINALS  },
01161     {JVMCLASS_JAVA_LANG_STRING, NATIVE_TABLE_JLSTRING_ORDINALS },
01162     {JVMCLASS_JAVA_LANG_THREAD, NATIVE_TABLE_JLTHREAD_ORDINALS },
01163 
01164     /*
01165      * Add more classes here
01166      */
01167 
01168 
01169     /* End of table marker, regardless of static array[size] */
01170     { 
01171         CHEAT_AND_USE_NULL_TO_INITIALIZE,
01172         {
01173             {
01174                 JVMCFG_JLOBJECT_NMO_NULL,
01175                 CHEAT_AND_USE_NULL_TO_INITIALIZE,
01176                 CHEAT_AND_USE_NULL_TO_INITIALIZE
01177             }
01178         }
01179     }
01180 };
01181 
01182 /*@} */ /* End of grouped definitions */
01183 
01184 
01185 /*!
01186  * @brief Associate class name string with its local native
01187  * method interface connection.
01188  *
01189  *
01190  * @param pcfs        ClassFile pointer of a class referencing a
01191  *                    native method, local or otherwise.  The following
01192  *                    constant_pool indices are all relative to this
01193  *                    ClassFile.
01194  *
01195  * @param clsnameidx  constant_pool index in @b pcfs of class name to
01196  *                    locate in class table.
01197  *
01198  * @param mthnameidx  constant_pool index in @b pcfs of method name to
01199  *                    locate in @b clsnameidx.
01200  *
01201  * @param mthdescidx  constant_pool index in @b pcfs of method
01202  *                    description with method name @b mthnameidx
01203  *                    to locate in @b clsnameidx.
01204  *
01205  * @param find_registerNatives When @link #rtrue rtrue@endlink,
01206  *                      will return the ordinal for
01207  *                      @link #JVMCFG_JLOBJECT_NMO_REGISTER 
01208                                JVMCFG_JLOBJECT_NMO_REGISTER@endlink and
01209  *                      @link #JVMCFG_JLOBJECT_NMO_UNREGISTER 
01210                                JVMCFG_JLOBJECT_NMO_UNREGISTER@endlink
01211  *                      as well as the other ordinals.  Once JVM
01212  *                      initialization is complete, this should always
01213  *                      be @link #rfalse rfalse@endlink because
01214  *                      all future classes should
01215  *                      @e never have local ordinals.
01216  *
01217  *
01218  * @returns ordinal definition for this method, or @link
01219             #jvm_native_method_ordinal_null
01220             jvm_native_method_ordinal_null@endlink if not found.
01221  *
01222  */
01223 jvm_native_method_ordinal
01224     native_locate_local_method(ClassFile *pcfs,
01225                                jvm_constant_pool_index clsnameidx,
01226                                jvm_constant_pool_index mthnameidx,
01227                                jvm_constant_pool_index mthdescidx,
01228                                rboolean            find_registerNatives)
01229 {
01230     rint nmoclsnameidx;
01231     rint nmomthnameidx;
01232 
01233     for (nmoclsnameidx= 0;
01234          rnull != native_local_method_list[nmoclsnameidx].clsname;
01235          nmoclsnameidx++)
01236     {
01237         if (0 == utf_prchar_pcfs_strcmp(
01238                      native_local_method_list[nmoclsnameidx].clsname,
01239                      pcfs,
01240                      clsnameidx))
01241         {
01242             for (nmomthnameidx= 0;
01243                  jvm_native_method_ordinal_null !=
01244                          native_local_method_list[nmoclsnameidx]
01245                            .nlmo_map[nmomthnameidx]
01246                              .nmord;
01247                  nmomthnameidx++)
01248             {
01249                 if (0 == utf_prchar_pcfs_strcmp(
01250                              native_local_method_list[nmoclsnameidx]
01251                                .nlmo_map[nmomthnameidx]
01252                                  .mthname,
01253                              pcfs, 
01254                              mthnameidx))
01255                 {
01256                     if (0 == utf_prchar_pcfs_strcmp(
01257                                  native_local_method_list[nmoclsnameidx]
01258                                    .nlmo_map[nmomthnameidx]
01259                                      .mthdesc,
01260                                  pcfs, 
01261                                  mthdescidx))
01262                     {
01263                         return(native_local_method_list[nmoclsnameidx]
01264                                  .nlmo_map[nmomthnameidx]
01265                                    .nmord);
01266                     }
01267                 }
01268             }
01269         }
01270     }
01271 
01272     if (rtrue == find_registerNatives)
01273     {
01274         /* Check two special cases, register/unregister native methods*/
01275         if (0 == utf_prchar_pcfs_strcmp(JVMCFG_REGISTER_NATIVES_METHOD,
01276                                         pcfs, 
01277                                         mthnameidx))
01278         {
01279             if (0 ==
01280                 utf_prchar_pcfs_strcmp(JVMCFG_REGISTER_NATIVES_PARMS,
01281                                        pcfs, 
01282                                        mthdescidx))
01283             {
01284                 return(JVMCFG_JLOBJECT_NMO_REGISTER);
01285             }
01286         }
01287 
01288         if (0 ==
01289             utf_prchar_pcfs_strcmp(JVMCFG_UNREGISTER_NATIVES_METHOD,
01290                                    pcfs, 
01291                                    mthnameidx))
01292         {
01293             if (0 ==
01294                 utf_prchar_pcfs_strcmp(JVMCFG_UNREGISTER_NATIVES_PARMS,
01295                                        pcfs, 
01296                                        mthdescidx))
01297             {
01298                 return(JVMCFG_JLOBJECT_NMO_UNREGISTER);
01299             }
01300         }
01301     }
01302 
01303     /* Not found */
01304     return(jvm_native_method_ordinal_null);
01305 
01306 } /* END of native_locate_local_method() */
01307 
01308 
01309 /*!
01310  * @brief Invoke a native method, either local or full JNI.
01311  *
01312  * Local native methods are normally called through this interface
01313  * using their ordinal number assignment.  Normal JNI native methods
01314  * are invoked with the
01315  * @link #JLOBJECT_NMO_NULL JLOBJECT_NMO_NULL@endlink ordinal and with
01316  * normal class and method information.
01317  *
01318  * @attention A necessary restriction of this local native method
01319  *            interface is that the real machine functions that
01320  *            are called as Java native methods <em>MAY NOT</em>
01321  *            attempt to call Java virtual functions.  Code that
01322  *            needs to do this should use the full JNI instead.
01323  *            The same is true about Java-domain access to data.
01324  *            As a practical matter, this should never be an issue
01325  *            because the suite of local native methods is concerned
01326  *            with JVM core internals, that is, in the real machine
01327  *            domain, and will probably never care about Java-domain
01328  *            functionality.
01329  *
01330  * @attention All local native methods @e must throw @b Errors through
01331  *            @link
01332               #exit_throw_exception() exit_throw_exception()@endlink
01333  *            so as to avoid crossing from real- to Java-domain
01334  *            functionality.  Each and every possible subclass of
01335  *            @c @b java.lang.Error and every possible subclass
01336  *            of @c @b java.lang.Exception is available through
01337  *            this interface.  It will be loaded and an instance created
01338  *            in the usual manner after being thrown by the native
01339  *            code through this function.  The result, of course, is
01340  *            a normal state of the JVM, which will be shut down
01341  *            in the normal fashion for @b Errors, but will only
01342  *            stop the thread for @b Exceptions.
01343  *
01344  * @param thridx     JVM thread where request came from.
01345  *
01346  * @param nmord      Ordinal number definition of local native method.
01347  *
01348  * @param clsidx     Class table index of native method to invoke.
01349  *
01350  * @param mthnameidx Class file constant_pool index of name of native
01351  *                   method to invoke.  This entry must be a
01352  *                   CONSTANT_Utf8_info string containing an
01353  *                   unqualified method name.
01354  *
01355  * @param mthdescidx Class file constant_pool index of descriptor of
01356  *                   method to invoke.  This entry must be a
01357  *                   CONSTANT_Utf8_info string containing the
01358  *                   descriptor of an unqualified method name.
01359  *
01360  *
01361  * @returns @link #rvoid rvoid@endlink.  May throw an error or
01362  *          exception of @e any kind from with the native code.
01363  *
01364  */
01365 rvoid native_run_method(jvm_thread_index          thridx,
01366                         jvm_native_method_ordinal nmord,
01367                         jvm_class_index           clsidx,
01368                         jvm_constant_pool_index   mthnameidx,
01369                         jvm_constant_pool_index   mthdescidx)
01370 {
01371     /*!
01372      * Verify that this local native method ordinal is both
01373      * unique and complete.
01374      */
01375     native_verify_ordinal_definition(nmord);
01376 
01377     switch(nmord)
01378     {
01379         /*!
01380          * Invoke JNI methods, not local native methods
01381          */
01382         case JVMCFG_JLOBJECT_NMO_NULL:
01383             /*!
01384              * @todo Invoke the full JNI interface for this method at
01385              *       this place.  Additional parameters will be needed.
01386              *
01387              * Currently, the JNI interface is stubbed out here.
01388              * The implementation goes something like this:
01389              *
01390              *     env = make_JNIEnv_pointer_from_pjvm();
01391              *             (to be done during jvm_init() at startup)
01392              *
01393              *     System.LoadLibrary("SomeJniMethodLib.so");
01394              *             (to be done in Java class initialization,
01395              *             requires @c @b dlopen(3), @c @b dlsym(3),
01396              *             etc.  Recommend adding function
01397              *             method_load_jni_lib() in this source file
01398              *             for this purpose.)
01399              *
01400              *     registerNatives();
01401              *             (to be done in Java class initialization)
01402              *
01403              *     void *pjni = method_resolve_jni(clsidx,
01404              *                                     mthnameidx,
01405              *                                     mthdescidx);
01406              *             (Recommend adding this function in this
01407              *             source file for this purpose.)
01408              *
01409              * Finally, invoke JNI method, per return type.
01410              * The parameters are on the the JVM thread's STACK()
01411              * now, so simply reference the stack frame for the
01412              * parameter list.  To be decided:  How to take the
01413              * return code and pass it back out.  Suggest doing
01414              * the same thing as the local native methods by
01415              * capturing its value, POP_FRAME(), then PUSH(rc).
01416              *
01417              *                  (*pjni)(&GET_SP(thridx)); ... (jvoid)
01418              *     jint    rc = (*pjni)(&GET_SP(thridx));
01419              *     jfloat  rc = (*pjni)(&GET_SP(thridx));
01420              *     jlong   rc = (*pjni)(&GET_SP(thridx));
01421              *     jdouble rc = (*pjni)(&GET_SP(thridx));
01422              *
01423              *     POP_FRAME(thridx);
01424              *     PUSH(thridx, rc); ... adjusted for return type
01425              *
01426              * The only problem with this for now is that the
01427              * STACK() in this implementation is a push-UP stack,
01428              * which means that the @e first item pushed has the
01429              * lowest real machine address.  Many stacks are a
01430              * push-DOWN type, which means that the @e last item
01431              * pushed has the lowest real machine address.  This
01432              * will need to be examined to see how it affects the
01433              * JNI implementation connectivity to the library.
01434              * It should not be too much of a problem to change
01435              * the STACK() implementation to be push-DOWN, but
01436              * if JNI is a highly modular interface, then this
01437              * implementation of it should be handle either type
01438              * of STACK() with equal facility.
01439              *
01440              */
01441             if (rfalse == JVMCFG_IGNORE_NATIVE_METHOD_CALLS)
01442             {
01443                 exit_throw_exception(EXIT_JVM_METHOD,
01444                                   JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
01445 /*NOTREACHED*/
01446             }
01447 
01448             jvalue rc;
01449             jint   rcms, rcls;
01450 
01451             switch (method_return_type(clsidx, mthdescidx))
01452             {
01453                 case BASETYPE_CHAR_B:
01454                 case BASETYPE_CHAR_C:
01455                 case BASETYPE_CHAR_I:
01456                 case BASETYPE_CHAR_S:
01457                 case BASETYPE_CHAR_Z:
01458                     rc._jint = 0;
01459                     PUSH(thridx, rc._jint);
01460                     return;
01461 
01462                 case BASETYPE_CHAR_J:
01463                     rc._jlong = 0;
01464                     bytegames_split_jlong(rc._jlong, &rcms, &rcls);
01465                     PUSH(thridx, rcms);
01466                     PUSH(thridx, rcls);
01467                     return;
01468 
01469                 case BASETYPE_CHAR_L:
01470                     rc._jobjhash = jvm_object_hash_null;
01471                     PUSH(thridx, rc._jobjhash);
01472                     return;
01473 
01474                 case BASETYPE_CHAR_D:
01475                     rc._jdouble = 0.0;
01476                     bytegames_split_jdouble(rc._jdouble, &rcms, &rcls);
01477                     PUSH(thridx, rcms);
01478                     PUSH(thridx, rcls);
01479                     return;
01480 
01481                 case BASETYPE_CHAR_F:
01482                     rc._jfloat = 0.0;
01483                     PUSH(thridx, rc._jfloat);
01484                     return;
01485 
01486                 case BASETYPE_CHAR_ARRAY:
01487                     rc._jarray = jvm_object_hash_null;
01488                     PUSH(thridx, rc._jarray);
01489                     return;
01490 
01491                 case METHOD_CHAR_VOID:
01492                     return;
01493 
01494                 default:
01495                 /*!
01496                  * @todo  Which is the better error, @b VerifyError
01497                  *        or @b NoSuchMethodError ?
01498                  */
01499                 exit_throw_exception(EXIT_JVM_METHOD,
01500                                      JVMCLASS_JAVA_LANG_VERIFYERROR);
01501 /*NOTREACHED*/
01502                 return; /* Satisfy compiler */
01503             }
01504 
01505             return; /* Satisfy compiler */
01506 
01507         /*!
01508          * Invoke local native methods that return (jvoid)
01509          */
01510         NATIVE_TABLE_JLOBJECT_JVOID
01511         NATIVE_TABLE_JLCLASS_JVOID
01512         NATIVE_TABLE_JLSTRING_JVOID
01513         NATIVE_TABLE_JLTHREAD_JVOID
01514 
01515         /*
01516          * Add @b NATIVE_TABLE_JLxxxx_JVOID entries
01517          * here @b WITHOUT colon (:) characters...
01518          */
01519 
01520 
01521             /* (rvoid) ... obviously redundant */
01522                        native_run_local_return_jvoid(nmord, thridx);
01523             return;
01524 
01525         /*!
01526          * Invoke local native methods that return (jobject),
01527          * known to this implementation as (jvm_object_hash).
01528          */
01529         NATIVE_TABLE_JLOBJECT_JOBJECT
01530         NATIVE_TABLE_JLCLASS_JOBJECT
01531         NATIVE_TABLE_JLSTRING_JOBJECT
01532         NATIVE_TABLE_JLTHREAD_JOBJECT
01533 
01534         /*
01535          * Add @b NATIVE_TABLE_JLxxxx_JOBJECT entries
01536          * here @b WITHOUT colon (:) characters...
01537          */
01538 
01539 
01540             (rvoid) native_run_local_return_jobject(nmord, thridx);
01541             return;
01542 
01543         /*!
01544          * Invoke local native methods that return (jint)
01545          */
01546         NATIVE_TABLE_JLOBJECT_JINT
01547         NATIVE_TABLE_JLCLASS_JINT
01548         NATIVE_TABLE_JLSTRING_JINT
01549         NATIVE_TABLE_JLTHREAD_JINT
01550 
01551         /*
01552          * Add @b NATIVE_TABLE_JLxxxx_JINT entries
01553          * here @b WITHOUT colon (:) characters...
01554          */
01555 
01556 
01557             (rvoid) native_run_local_return_jint(nmord, thridx);
01558             return;
01559 
01560         /*!
01561          * Invoke local native methods that return (jfloat)
01562          */
01563         NATIVE_TABLE_JLOBJECT_JFLOAT
01564         NATIVE_TABLE_JLCLASS_JFLOAT
01565         NATIVE_TABLE_JLSTRING_JFLOAT
01566         NATIVE_TABLE_JLTHREAD_JFLOAT
01567 
01568         /*
01569          * Add @b NATIVE_TABLE_JLxxxx_JFLOAT entries
01570          * here @b WITHOUT colon (:) characters...
01571          */
01572 
01573 
01574             (rvoid) native_run_local_return_jfloat(nmord, thridx);
01575             return;
01576 
01577         /*!
01578          * Invoke local native methods that return (jlong)
01579          */
01580         NATIVE_TABLE_JLOBJECT_JLONG
01581         NATIVE_TABLE_JLCLASS_JLONG
01582         NATIVE_TABLE_JLSTRING_JLONG
01583         NATIVE_TABLE_JLTHREAD_JLONG
01584 
01585         /*
01586          * Add @b NATIVE_TABLE_JLxxxx_JLONG entries
01587          * here @b WITHOUT colon (:) characters...
01588          */
01589 
01590 
01591             (rvoid) native_run_local_return_jlong(nmord, thridx);
01592             return;
01593 
01594         /*!
01595          * Invoke local native methods that return (jdouble)
01596          */
01597         NATIVE_TABLE_JLOBJECT_JDOUBLE
01598         NATIVE_TABLE_JLCLASS_JDOUBLE
01599         NATIVE_TABLE_JLSTRING_JDOUBLE
01600         NATIVE_TABLE_JLTHREAD_JDOUBLE
01601 
01602         /*
01603          * Add @b NATIVE_TABLE_JLxxxx_JDOUBLE entries
01604          * here @b WITHOUT colon (:) characters...
01605          */
01606 
01607 
01608             (rvoid) native_run_local_return_jdouble(nmord, thridx);
01609             return;
01610 
01611 
01612         /*!
01613          * IGNORE local native method registration.
01614          */
01615         case JVMCFG_JLOBJECT_NMO_REGISTER:
01616             /* Okay, I'm registered. (Nothing needs to be done here.) */
01617             return;
01618 
01619 
01620 
01621         /*!
01622          * IGNORE local native method un-registration.
01623          */
01624         case JVMCFG_JLOBJECT_NMO_UNREGISTER:
01625             /* Okay, I'm unregistered.(Nothing needs to be done here.)*/
01626             return;
01627 
01628 
01629         /*!
01630          * Somebody goofed. There is an incomplete definition somewhere.
01631          */
01632         default:
01633             /*!
01634              * Due to the invocation of @link
01635                #native_verify_ordinal_definition()
01636                 native_verify_ordinal_definition()@endlink above,
01637              * this condition @e should not be reached unless one
01638              * of the NATIVE_TABLE_JLxxxxx_RETURNTYPE macros does not
01639              * have all of the entries that it needs.
01640              */
01641             exit_throw_exception(EXIT_JVM_INTERNAL,
01642                                  JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
01643 /*NOTREACHED*/
01644             return; /* Satisfy compiler */
01645     }
01646     return; /* Satisfy compiler */
01647 
01648 } /* END of native_run_method() */
01649 
01650 
01651 /* EOF */
01652 

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