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