JNI native methods are Java methods that are described in Java, but are not implemented in Java per se. Instead, they are implemented in a computer language that is compiled into the native machine code of the real computing platform-- hence the appellation native. Selected native methods are actually part of the source code for the Java Virtual Machine itself, yet may be referenced through the JNI interface. Both types of native methods are supported in this implementation of the JVM. However, most of the code in this source file is concerned with local native methods. There is a single hook in native_run_method() that deals with the normal JNI interface, and nothing else is required.
Local native methods are JNI methods that are implemented within the core of the JVM code since they involve an intimate acquaintance with its internal structures. Since they are implemented in this way, there is no need to prepare a full JNI call to reference them. At class load time, each of these methods is discovered by native_locate_local_method() to be found in the tables generated by macros in each of the jlXxxx.h header files and referenced here. A local native method ordinal number is assigned to each one. At run time, this ordinal number is examined by native_run_method() when a native method is invoked by the Java byte code. If the ordinal number is JVMCFG_JLOBJECT_NMO_NULL, then JNI interface is invoked in the normal manner. If not, the ordinal is used to select which native method implementation is invoked. Each ordinal number is guaranteed to be unique by a combination of compilation checking of an enum value
and runtime checking by native_verify_ordinal_definition(). The former checks uniqueness within a class at compile time. The latter checks collisions between classes at compile time and checks for undefined values at run time.
The Java class java.lang.Thread is
a good example to show how to add normal JNI native methods and JNI local native methods because of the wide variety of native methods that are implemented in the initial version of this JNI implementation. (In this case, all of them are local native methods, but this class will serve as an example for the general case of a normal JNI native method.)
Following is the procedure to add a native method to any class. At the end of this procedure, instructions are given for how to add a new class with native methods, hypothetically named java.lang.NewClassType.
When file names containing the class name string "<b>Thread</b>" are referenced in the following example, use the java.lang.Thread equivalent
file name and simply substitute the string "<b>NewClassType</b>" for it. In fact, copying the java.lang.Thread source
file(s) to the new class name is a suggested way to start writing for the native method requirements of a new class.
Here is how to connect a JNI native method into the JVM:
native int xxx(boolean b)
. JNIEXPORT jint JNICALL java_lang_Thread_xxx(JNIEnv *, jboolean)
in the corresponding 'C' source file java_lang_Thread.c. If this is a normal JNI native method, this is the end of the matter. If it is a local native method, also add its logic to the JVM core code:
rint jlThread_xxx(rboolean b)
in the JVM core source file jlThread.c. This function will likely also be referenced from within the core code itself without regard to the JNI hooks, but be careful to use only those data types in its function prototype that will compile in both the JNI environment and in the JVM core environment. As to the contents of the function, the JNI code never sees that part. It sees only the prototype definition in jlThread.h. (See jlObject.h for further explanation.)
If this is a local native method in an existing class, this completes the procedure. However, if this new native method is part of a class that is not yet supported by this present source file, such as java.lang.NewClassType as
mentioned at the beginning of this narrative, then the remaining steps complete the procedure of connecting the local methods to the JVM for the new NewClassType files once they are written:
#define JLNEWCLASSTYPE_LOCAL_DEFINED #include "jlNewClassType.h"
{JVMCLASS_JAVA_LANG_NEWCLASSTYPE, NATIVE_TABLE_JLNEWCLASSTYPE_ORDINALS },
This completes the JNI interconnection process.
Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
Licensed under the Apache License, Version 2.0 ("the License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.
Definition in file native.c.
#include "arch.h"
#include "jvmcfg.h"
#include "classfile.h"
#include "exit.h"
#include "jvm.h"
#include "jvmclass.h"
#include "method.h"
#include "util.h"
#include "utf.h"
#include "jlObject.h"
#include "jlClass.h"
#include "jlString.h"
#include "jlThread.h"
Go to the source code of this file.
Data Structures | |||||||
struct | native_local_method_map | ||||||
Associate a class name with its local native method ordinal numbers and its JVM method name and description strings. More... | |||||||
struct | native_local_method_ordinal_map | ||||||
Associate a local native method ordinal number with its JVM method name and description string. More... | |||||||
JVM stack frame access for local native method interface. | |||||||
Map JVM operand stack parameters to real machine native method implementation by popping parameters from JVM stack into real machine local variables that are then passed to local native methods. | |||||||
#define | GET_CURRENT_CLSIDX(thridx) GET_PC_FIELD(thridx, clsidxCURR, clsidx) | ||||||
Retrieve current class index parameter from the top of the JVM stack into real machine local variable clsidxCURR for use as a parameter to local native static method calls. | |||||||
#define | POP_JDOUBLE(thridx) | ||||||
Retrieve a (jdouble) method parameter from the top of the JVM stack into real machine local variable jdparm for use as a parameter to local native method calls. | |||||||
#define | POP_JFLOAT(thridx) POP(thridx, jfparm, jfloat) | ||||||
Retrieve a (jfloat) method parameter from the top of the JVM stack into real machine local variable jfparm for use as a parameter to local native method calls. | |||||||
#define | POP_JINT(thridx) POP(thridx, jiparm, jint) | ||||||
Retrieve a (jint) method parameter from the top of the JVM stack into real machine local variable jiparm for use as a parameter to local native method calls. | |||||||
#define | POP_JLONG(thridx) | ||||||
Retrieve a (jlong) method parameter from the top of the JVM stack into real machine local variable jlparm for use as a parameter to local native method calls. | |||||||
#define | POP_JOBJECT(thridx) POP(thridx, joparm, jvm_object_hash) | ||||||
Retrieve a (jobject) method parameter from the top of the JVM stack into real machine local variable joparm for use as a parameter to local native method calls. | |||||||
#define | POP_THIS_OBJHASH(thridx) POP(thridx, objhashTHIS, jvm_object_hash) | ||||||
Retrieve this object hash parameter from the top of the JVM stack into real machine local variable objhashTHIS for use as a parameter to local native object instance method calls. | |||||||
Native local method mapping structures | |||||||
#define | NLML_MAX_CLASSES 5 | ||||||
Number of native_local_method_map slots in the largest class with local native methods. | |||||||
#define | NLMO_MAX_SLOTS 25 | ||||||
Number of native_local_method_ordinal_map slots in the largest class with local native methods. | |||||||
native_local_method_map | native_local_method_list [5] | ||||||
Complete and authoritative list of Java classes implementing local native methods. Each jlXxxxx.h header file defines a suite of NATIVE_TABLE_JLxxxxx_ORDINALS. This suite is entered here for processing by the local native method logic. | |||||||
Real machine automatic local variable stack frame conversion. | |||||||
List of real machine local variables used as scratchpad for the several POP_xxx() macros that retrieve JVM stack parms for distribution to local native methods. Mix and match in the various functions according to which operands are to be parsed. | |||||||
#define | POP_SCRATCHPAD_JDOUBLE | ||||||
#define | POP_SCRATCHPAD_JFLOAT jint jfparm | ||||||
#define | POP_SCRATCHPAD_JINT jint jiparm | ||||||
#define | POP_SCRATCHPAD_JLONG | ||||||
#define | POP_SCRATCHPAD_JOBJECT jint joparm | ||||||
#define | POP_SCRATCHPAD_JVM | ||||||
Local native method interface. | |||||||
Map JVM stack frame to real machine native method implementation, invoke the actual real function, and report the results.
| |||||||
static jdouble | native_run_local_return_jdouble (jvm_native_method_ordinal nmord, jvm_thread_index thridx) | ||||||
Local native equivalent of native double mthname() . | |||||||
static jfloat | native_run_local_return_jfloat (jvm_native_method_ordinal nmord, jvm_thread_index thridx) | ||||||
Local native equivalent of native float mthname() . | |||||||
static jint | native_run_local_return_jint (jvm_native_method_ordinal nmord, jvm_thread_index thridx) | ||||||
Local native equivalent of native int mthname() , also used for (boolean ), (byte ), (char ), and (short ) return types. | |||||||
static jlong | native_run_local_return_jlong (jvm_native_method_ordinal nmord, jvm_thread_index thridx) | ||||||
Local native equivalent of native long mthname() . | |||||||
static jvm_object_hash | native_run_local_return_jobject (jvm_native_method_ordinal nmord, jvm_thread_index thridx) | ||||||
Local native equivalent of native jobject mthname() . | |||||||
static rvoid | native_run_local_return_jvoid (jvm_native_method_ordinal nmord, jvm_thread_index thridx) | ||||||
Local native equivalent of native void mthname() . | |||||||
Defines | |||||||
#define | JLCLASS_LOCAL_DEFINED | ||||||
Local implementation mode inclusion of jlClass.h. | |||||||
#define | JLOBJECT_LOCAL_DEFINED | ||||||
Local implementation mode inclusion of jlObject.h. | |||||||
#define | JLSTRING_LOCAL_DEFINED | ||||||
Local implementation mode inclusion of jlString.h. | |||||||
#define | JLTHREAD_LOCAL_DEFINED | ||||||
Local implementation mode inclusion of jlThread.h. | |||||||
Functions | |||||||
static void | native_c_dummy (void) | ||||||
jvm_native_method_ordinal | native_locate_local_method (ClassFile *pcfs, jvm_constant_pool_index clsnameidx, jvm_constant_pool_index mthnameidx, jvm_constant_pool_index mthdescidx, rboolean find_registerNatives) | ||||||
Associate class name string with its local native method interface connection. | |||||||
rvoid | native_run_method (jvm_thread_index thridx, jvm_native_method_ordinal nmord, jvm_class_index clsidx, jvm_constant_pool_index mthnameidx, jvm_constant_pool_index mthdescidx) | ||||||
Invoke a native method, either local or full JNI. | |||||||
static rvoid | native_verify_ordinal_definition (jvm_native_method_ordinal nmord) | ||||||
Verify the validity of a native method ordinal number. | |||||||
Variables | |||||||
static char * | native_c_copyright = "\0" "$URL: https://svn.apache.org/path/name/native.c $ $Id: native.c 0 09/28/2005 dlydick $" " " "Copyright 2005 The Apache Software Foundation or its licensors, as applicable." |
|
Local implementation mode inclusion of jlObject.h.
|
|
Local implementation mode inclusion of jlClass.h.
|
|
Local implementation mode inclusion of jlString.h.
|
|
Local implementation mode inclusion of jlThread.h.
|
|
Value: jvm_class_index clsidxCURR; \ jvm_object_hash objhashTHIS Definition at line 405 of file native.c. Referenced by native_run_local_return_jint(), native_run_local_return_jobject(), and native_run_local_return_jvoid(). |
|
Definition at line 409 of file native.c. Referenced by native_run_local_return_jint(). |
|
Definition at line 412 of file native.c. Referenced by native_run_local_return_jint(), and native_run_local_return_jvoid(). |
|
|
|
Value: Definition at line 418 of file native.c. Referenced by native_run_local_return_jint(), and native_run_local_return_jvoid(). |
|
Value: |
|
Retrieve current class index parameter from the top of the JVM stack into real machine local variable clsidxCURR for use as a parameter to local native
Definition at line 457 of file native.c. Referenced by native_run_local_return_jint(), native_run_local_return_jobject(), and native_run_local_return_jvoid(). |
|
Retrieve
Definition at line 473 of file native.c. Referenced by native_run_local_return_jint(), native_run_local_return_jobject(), and native_run_local_return_jvoid(). |
|
Retrieve a (jobject) method parameter from the top of the JVM stack into real machine local variable joparm for use as a parameter to local native method calls.
Definition at line 489 of file native.c. Referenced by native_run_local_return_jint(). |
|
Retrieve a (jint) method parameter from the top of the JVM stack into real machine local variable jiparm for use as a parameter to local native method calls.
Definition at line 505 of file native.c. Referenced by native_run_local_return_jint(), and native_run_local_return_jvoid(). |
|
Retrieve a (jfloat) method parameter from the top of the JVM stack into real machine local variable jfparm for use as a parameter to local native method calls.
|
|
Value: POP(thridx, jlpls, jint); \ POP(thridx, jlpms, jint); \ jlparm = bytegames_combine_jlong(jlpms, jlpls)
Definition at line 540 of file native.c. Referenced by native_run_local_return_jint(), and native_run_local_return_jvoid(). |
|
Value: POP(thridx, jlpls, jint); \ POP(thridx, jlpms, jint); \ jdparm = bytegames_combine_jdouble(jlpms, jlpls)
|
|
Number of native_local_method_map slots in the largest class with local native methods. This integer should be increased to accomodate the number of Java classes in the table. Let the compiler complains about too many initializers in the native_local_method_list[] array and increase the value so that just the right number of array elements are allocated. (There is no point in allocating extra slots because they will sit empty and unused.) |
|
Number of native_local_method_ordinal_map slots in the largest class with local native methods. This integer should be increased to accomodate the maximum class. Let the compiler complains about too many initializers in native_local_method_list.nlmo_map and then increase the value so that just the right number of elements are allocated for the largest class. |
|
|
|
Local native equivalent of
The JVM returns from a Definition at line 597 of file native.c. References EXIT_JVM_INTERNAL, exit_throw_exception(), GET_CURRENT_CLSIDX, JLOBJECT_NMO_WAIT4EVER, JLOBJECT_NMO_WAITTIMED, jlObject_wait4ever(), jlObject_waittimed(), jlThread_interrupt(), jlThread_join4ever(), jlThread_jointimed(), jlThread_jointimed_nanos(), JLTHREAD_NMO_INTERRUPT, JLTHREAD_NMO_JOIN4EVER, JLTHREAD_NMO_JOINTIMED, JLTHREAD_NMO_JOINTIMED_NANOS, JLTHREAD_NMO_RESUME, JLTHREAD_NMO_SETDAEMON, JLTHREAD_NMO_STOP, JLTHREAD_NMO_SUSPEND, JLTHREAD_NMO_YIELD, jlThread_resume(), jlThread_setDaemon(), jlThread_stop(), jlThread_suspend(), jlThread_yield(), JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR, POP_JINT, POP_JLONG, POP_SCRATCHPAD_JINT, POP_SCRATCHPAD_JLONG, POP_SCRATCHPAD_JVM, and POP_THIS_OBJHASH. |
|
Local native equivalent of
The JVM returns from a Definition at line 699 of file native.c. References EXIT_JVM_INTERNAL, exit_throw_exception(), GET_CURRENT_CLSIDX, jlObject_getClass(), JLOBJECT_NMO_GETCLASS, jlThread_currentThread(), JLTHREAD_NMO_CURRENTTHREAD, JVMCFG_JLOBJECT_NMO_NULL, JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR, POP_SCRATCHPAD_JVM, POP_THIS_OBJHASH, and PUSH. |
|
|
Local native equivalent of
The JVM returns from a Definition at line 886 of file native.c. References EXIT_JVM_INTERNAL, exit_throw_exception(), JVMCFG_JLOBJECT_NMO_NULL, JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR, and PUSH. |
|
Local native equivalent of
The JVM returns from a Definition at line 920 of file native.c. References bytegames_split_jlong(), EXIT_JVM_INTERNAL, exit_throw_exception(), JVMCFG_JLOBJECT_NMO_NULL, JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR, and PUSH. |
|
Local native equivalent of
The JVM returns from a Definition at line 959 of file native.c. References bytegames_split_jdouble(), EXIT_JVM_INTERNAL, exit_throw_exception(), JVMCFG_JLOBJECT_NMO_NULL, JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR, and PUSH. |
|
Verify the validity of a native method ordinal number.
The purpose of this function is to verify that all of the ordinal numbers are listed in the For internal use only. Although this function is invoked from native_locate_local_method(), the real purpose is fulfilled at compile time by verifying that there is a completely unique set of ordinals across all classes. Invoking it at run time adds to this integrity by verifying that a native method invocation is using an ordinal that actually exists.
Definition at line 1021 of file native.c. References EXIT_JVM_INTERNAL, exit_throw_exception(), JVMCFG_JLOBJECT_NMO_NULL, JVMCFG_JLOBJECT_NMO_REGISTER, JVMCFG_JLOBJECT_NMO_UNREGISTER, JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR, NATIVE_TABLE_JLCLASS, NATIVE_TABLE_JLOBJECT, NATIVE_TABLE_JLSTRING, and NATIVE_TABLE_JLTHREAD. |
|
Associate class name string with its local native method interface connection.
< null-terminated string form of METHOD_CHAR_OPEN_PARM < null-terminated string form of METHOD_CHAR_VOID < null-terminated string form of METHOD_CHAR_OPEN_PARM < null-terminated string form of METHOD_CHAR_OPEN_PARM < null-terminated string form of METHOD_CHAR_VOID Definition at line 1266 of file native.c. Referenced by linkage_resolve_class(). |
|
Invoke a native method, either local or full JNI. Local native methods are normally called through this interface using their ordinal number assignment. Normal JNI native methods are invoked with the JLOBJECT_NMO_NULL ordinal and with normal class and method information.
Invoke JNI methods, not local native methods
env = make_JNIEnv_pointer_from_pjvm(); (to be done during jvm_init() at startup)
System.LoadLibrary("SomeJniMethodLib.so"); (to be done in Java class initialization, requires registerNatives(); (to be done in Java class initialization) void *pjni = method_resolve_jni(clsidx, mthnameidx, mthdescidx); (Recommend adding this function in this source file for this purpose.) Finally, invoke JNI method, per return type. The parameters are on the the JVM thread's STACK() now, so simply reference the stack frame for the parameter list. To be decided: How to take the return code and pass it back out. Suggest doing the same thing as the local native methods by capturing its value, POP_FRAME(), then PUSH(rc). (*pjni)(&GET_SP(thridx)); ... (jvoid) jint rc = (*pjni)(&GET_SP(thridx)); jfloat rc = (*pjni)(&GET_SP(thridx)); jlong rc = (*pjni)(&GET_SP(thridx)); jdouble rc = (*pjni)(&GET_SP(thridx)); POP_FRAME(thridx); PUSH(thridx, rc); ... adjusted for return type The only problem with this for now is that the STACK() in this implementation is a push-UP stack, which means that the first item pushed has the lowest real machine address. Many stacks are a push-DOWN type, which means that the last item pushed has the lowest real machine address. This will need to be examined to see how it affects the JNI implementation connectivity to the library. It should not be too much of a problem to change the STACK() implementation to be push-DOWN, but if JNI is a highly modular interface, then this implementation of it should be handle either type of STACK() with equal facility. < Signed byte < Unicode character < Integer < Signed short < Boolean, true or false < Long integer < an instance of class '/class/name' < Double-precision floating-point value < Single-precision floating-point value < Reference to one array dimension < No return type, instead: (rvoid) fn(p1,p2,...)
Invoke local native methods that return (jvoid)
< No
< No Invoke local native methods that return (jobject), known to this implementation as (jvm_object_hash).
< No Invoke local native methods that return (jint)
< No Invoke local native methods that return (jfloat)
< No
< No
< No
< No Invoke local native methods that return (jlong)
< No
< No
< No
< No Invoke local native methods that return (jdouble)
< No
< No
< No
< No IGNORE local native method registration. IGNORE local native method un-registration. Somebody goofed. There is an incomplete definition somewhere. Due to the invocation of native_verify_ordinal_definition() above, this condition should not be reached unless one of the NATIVE_TABLE_JLxxxxx_RETURNTYPE macros does not have all of the entries that it needs. Definition at line 1413 of file native.c. References EXIT_JVM_METHOD, exit_throw_exception(), and JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR. Referenced by object_run_method(), and opcode_run(). |
|
|
|
Initial value: { { "java/lang/Object" , { { JLOBJECT_NMO_GETCLASS, "getClass", "()Ljava/lang/Class" }, { JLOBJECT_NMO_HASHCODE, "hashCode", "()I" }, { JLOBJECT_NMO_WAIT4EVER, "wait", "()V" }, { JLOBJECT_NMO_WAIT4EVER, "wait", "(J)V" }, { 0 , ((rvoid *) 0) , ((rvoid *) 0) } } }, { "java/lang/Class" , { { JLCLASS_NMO_ISARRAY, "isArray", "()V" }, { JLCLASS_NMO_ISPRIMATIVE, "isPrimative", "()V" }, { 0 , ((rvoid *) 0) , ((rvoid *) 0) } } }, { "java/lang/String" , { { JLSTRING_NMO_INTERN, "intern", "()Ljava/lang/String" }, { 0 , ((rvoid *) 0) , ((rvoid *) 0) } } }, { "java/lang/Thread" , { { JLTHREAD_NMO_CURRENTTHREAD,"currentThread", "()Ljava/lang/Thread;" }, { JLTHREAD_NMO_YIELD, "yield", "()V" }, { JLTHREAD_NMO_INTERRUPT, "interrupt", "()V" }, { JLTHREAD_NMO_INTERRUPTED, "interrupted", "()Z" }, { JLTHREAD_NMO_ISINTERRUPTED,"isInterrupted", "()Z" }, { JLTHREAD_NMO_SLEEP, "sleep", "(J)V" }, { JLTHREAD_NMO_SLEEP_NANOS, "sleep", "(JI)V" }, { JLTHREAD_NMO_JOIN4EVER, "join", "()V" }, { JLTHREAD_NMO_JOINTIMED, "join", "(J)V" }, { JLTHREAD_NMO_JOINTIMED_NANOS, "join", "(JI)V" }, { JLTHREAD_NMO_ISALIVE, "isAlive", "()Z" }, { JLTHREAD_NMO_START, "start", "()V" }, { JLTHREAD_NMO_COUNTSTACKFRAMES, "countStackFrames", "()I" }, { JLTHREAD_NMO_HOLDSLOCK, "holdsLock", "(Ljava/lang/Object;)Z" }, { JLTHREAD_NMO_SETPRIORITY, "setPriority", "(I)V" }, { JLTHREAD_NMO_GETPRIORITY, "getPriority", "()I" }, { JLTHREAD_NMO_DESTROY, "destroy", "()V" }, { JLTHREAD_NMO_CHECKACCESS, "checkAccess", "()V" }, { JLTHREAD_NMO_SETDAEMON, "setDaemon", "(Z)V" }, { JLTHREAD_NMO_ISDAEMON, "isDaemon", "()Z" }, { JLTHREAD_NMO_STOP, "stop", "()V" }, { JLTHREAD_NMO_SUSPEND, "suspend", "()V" }, { JLTHREAD_NMO_RESUME, "resume", "()V" }, { 0 , ((rvoid *) 0) , ((rvoid *) 0) } } }, { ((rvoid *) 0) , { { 0 , ((rvoid *) 0) , ((rvoid *) 0) } } } }
|