You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ge...@apache.org on 2005/10/08 06:29:29 UTC
svn commit: r307257 [18/24] - in
/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm: ./ bootJVM/
bootJVM/jni/ bootJVM/jni/src/ bootJVM/jni/src/gnu/
bootJVM/jni/src/gnu/classpath/ bootJVM/jni/src/gnu/classpath/0.16/
bootJVM/jni/src/gnu/classpath...
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/native.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/native.c?rev=307257&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/native.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/native.c Fri Oct 7 21:27:56 2005
@@ -0,0 +1,1651 @@
+/*!
+ * @file native.c
+ *
+ * @brief Local native method interface between JNI and JVM.
+ *
+ * JNI native methods are Java methods that are described in
+ * Java, but are not implemented in Java <em>per se</em>. Instead,
+ * they are implemented in a computer language that is compiled into
+ * the native machine code of the real computing platform-- hence
+ * the appellation @e 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
+ * @e local native methods. There is a single hook in
+ * @link #native_run_method() native_run_method()@endlink that
+ * deals with the normal JNI interface, and nothing else is required.
+ *
+ * Local native methods are JNI methods that are implemented @e 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 @link
+ native_locate_local_method() native_locate_local_method()@endlink
+ * to be found in the tables generated by macros in each of the
+ * @link jvm/include/jlObject.h jlXxxx.h@endlink header files
+ * and referenced here. A <em>local native method ordinal number</em>
+ * is assigned to each one. At run time, this ordinal number is
+ * examined by @link #native_run_method() native_run_method()@endlink
+ * when a native method is invoked by the Java byte code.
+ * If the ordinal number is @link #JVMCFG_JLOBJECT_NMO_NULL
+ JVMCFG_JLOBJECT_NMO_NULL@endlink, 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 @c @b enum value and runtime checking by
+ * @link #native_verify_ordinal_definition()
+ native_verify_ordinal_definition()@endlink. 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 @c @b 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
+ * @c @b java.lang.NewClassType. When file names
+ * containing the class name string "<b>Thread</b>" are referenced
+ * in the following example, use the @c @b java.lang.Thread
+ * equivalent file name and simply substitute the string
+ * "<b>NewClassType</b>" for it. In fact, copying the
+ * @c @b 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:
+ *
+ * <ul>
+ * <li> Add the native method declaration to the Java source file
+ * @link jni/src/harmony/generic/0.0/src/java/lang/Thread.java
+ Thread.java@endlink. For this discussion, it will be called
+ * <b><code>native int xxx(boolean b)</code></b>.
+ * </li>
+ * <li> Write the native method implementation
+ * <b><code>JNIEXPORT jint JNICALL
+ java_lang_Thread_xxx(JNIEnv *, jboolean)</code></b>
+ * in the corresponding 'C' source file
+ @link jni/src/harmony/generic/0.0/src/java_lang_Thread.c
+ java_lang_Thread.c@endlink.
+ * </li>
+ * <li> Enter the function prototype into the JNI header file
+ * @link jni/src/harmony/generic/0.0/include/java_lang_Thread.h
+ java_lang_Thread.h@endlink.
+ * </li>
+ * </ul>
+ *
+ * If this is a @e normal JNI native method, this is the end of the
+ * matter. If it is a @e local native method, also add its logic
+ * to the JVM core code:
+ *
+ * <ul>
+ * <li> Add the implementation of the logic as the function
+ * <b><code>rint jlThread_xxx(rboolean b)</code></b> in the JVM
+ * core source file
+ * @link jvm/src/jlThread.c jlThread.c@endlink.
+ * This function will likely also be referenced from within the
+ * core code itself without regard to the JNI hooks, but be
+ * careful to use @e only those data types in its function
+ * prototype that will compile in both the JNI environment
+ * @e 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 @link jvm/include/jlThread.h
+ jlThread.h@endlink. (See @link jvm/include/jlObject.h
+ jlObject.h@endlink for further explanation.)
+ * </li>
+ * <li> Select a native method ordinal number for the
+ * @link #jlThread_nmo_enum jlThread_nmo_enum@endlink enumeration.
+ * It should be the next sequential number at the end of the final
+ * enumerator in the current edition of the
+ * @link #jlThread_nmo_enum jlThread_nmo_enum@endlink
+ * enumeration. If there is an overlap with a higher enumeration
+ * series, the compiler will inform of the conflict. The name
+ * should be directly according to the local native
+ * implementation's function name, prefixed in the same manner as
+ * the other enumerators as @link #JLTHREAD_NMO_CURRENTTHREAD
+ JLTHREAD_NMO_xxx@endlink. Some Java methods may have overloaded
+ * names, which will resolve to unique names in the JVM core
+ * code, so do @e not use the Java method name. Instead, use
+ * the local native method's JVM core code 'C' function name as
+ * the basis for this name. See for example @link
+ #JLTHREAD_NMO_JOINTIMED_NANOS
+ JLTHREAD_NMO_JOINTIMED_NANOS@endlink.
+ * </li>
+ * <li> Add the prototype definition to
+ * @link jvm/include/jlThread.h jlThread.h@endlink in the
+ * same manner and per the above argument type constraint.
+ * Again, name it and position it in the same manner as the
+ * existing functions as
+ * @link #jlThread_currentThread() jlThread_xxx()@endlink.
+ * </li>
+ * <li> Add a reference to the enumerator
+ * @link #JLTHREAD_NMO_CURRENTTHREAD JLTHREAD_NMO_xxx@endlink
+ * to the end of the list of ordinals for the switch statement
+ * fragment for the class in
+ * @link #NATIVE_TABLE_JLTHREAD NATIVE_TABLE_JLTHREAD@endlink.
+ * </li>
+ * <li> Add an entry for the method at the end of the ordinal
+ * definition table @link #NATIVE_TABLE_JLTHREAD_ORDINALS
+ NATIVE_TABLE_JLTHREAD_ORDINALS@endlink. The ordinal must
+ * match the name @link #JLTHREAD_NMO_CURRENTTHREAD
+ JLTHREAD_NMO_xxx@endlink entered above. The method name
+ * string must match the name of the Java method name @b xxx in
+ * the original Java source file @link
+ jni/src/harmony/generic/0.0/src/java/lang/Thread.java
+ Thread.java@endlink described above. The descriptor must
+ * match the descriptor in the JNI source file
+ * @link jni/src/harmony/generic/0.0/src/java_lang_Thread.c
+ java_lang_Thread.c@endlink (and associated header file
+ * @link jni/src/harmony/generic/0.0/include/java_lang_Thread.h
+ java_lang_Thread.h@endlink.) This association is the basis
+ * of mapping the local native methods to their class file
+ * references at link time.
+ * </li>
+ * <li> Add the local native method ordinal
+ * @link #JLTHREAD_NMO_CURRENTTHREAD JLTHREAD_NMO_xxx@endlink to
+ * one of the groupings according to its return type. This will
+ * assure that the return value is properly processed. Study
+ * existing code for how to properly pass the runtime parameters
+ * from the JVM stack into the local native method. For each
+ * of the return types:
+ *
+ * <ul>
+ * <li> for a @link #jvoid jvoid@endlink function return type, add
+ * the ordinal number to @link #NATIVE_TABLE_JLTHREAD_JVOID
+ NATIVE_TABLE_JLTHREAD_JVOID@endlink.
+ * </li>
+ * <li> for a @link #jvm_object_hash jobject@endlink function
+ * return type, add the ordinal number to
+ * @link #NATIVE_TABLE_JLTHREAD_JOBJECT
+ NATIVE_TABLE_JLTHREAD_JOBJECT@endlink.
+ * </li>
+ * <li> for a @link #jbyte jbyte@endlink function return type,
+ add the ordinal number to @link #NATIVE_TABLE_JLTHREAD_JINT
+ NATIVE_TABLE_JLTHREAD_JINT@endlink.
+ * </li>
+ * <li> for a @link #jboolean jboolean@endlink function return type,
+ * add the ordinal number to @link #NATIVE_TABLE_JLTHREAD_JINT
+ NATIVE_TABLE_JLTHREAD_JINT@endlink.
+ * </li>
+ * <li> for a @link #jshort jshort@endlink function return type,
+ * add the ordinal number to @link #NATIVE_TABLE_JLTHREAD_JINT
+ NATIVE_TABLE_JLTHREAD_JINT@endlink.
+ * </li>
+ * <li> for a @link #jchar jchar@endlink function return type,
+ * add the ordinal number to @link #NATIVE_TABLE_JLTHREAD_JINT
+ NATIVE_TABLE_JLTHREAD_JINT@endlink.
+ * </li>
+ * <li> for a @link #jshort jshort@endlink function return type,
+ * add the ordinal number to @link #NATIVE_TABLE_JLTHREAD_JINT
+ NATIVE_TABLE_JLTHREAD_JINT@endlink.
+ * </li>
+ * <li> for a @link #jint jint@endlink function return type,
+ * add the ordinal number to @link #NATIVE_TABLE_JLTHREAD_JINT
+ NATIVE_TABLE_JLTHREAD_JINT@endlink.
+ * </li>
+ * <li> for a @link #jfloat jfloat@endlink function return type,
+ * add the ordinal number to
+ * @link #NATIVE_TABLE_JLTHREAD_JFLOAT
+ NATIVE_TABLE_JLTHREAD_JFLOAT@endlink.
+ * </li>
+ * <li> for a @link #jlong jlong@endlink function return type,
+ * add the ordinal number to
+ * @link #NATIVE_TABLE_JLTHREAD_JLONG
+ NATIVE_TABLE_JLTHREAD_JLONG@endlink.
+ * </li>
+ * <li> for a @link #jdouble jdouble@endlink function return type,
+ * add the ordinal number to
+ * @link #NATIVE_TABLE_JLTHREAD_JDOUBLE
+ NATIVE_TABLE_JLTHREAD_JDOUBLE@endlink.
+ * </li>
+ * </ul>
+ *
+ * </li>
+ * <li> Add an reference to
+ @link #jlThread_currentThread() jlThread_xxx()@endlink
+ * into the appropriate function in this present source file
+ * according to its return type in a manner similar to the above
+ * categorization:
+ *
+ * <ul>
+ * <li> for a @link #jvoid jvoid@endlink functions, add the ordinal
+ * number to @link #native_run_local_return_jvoid()
+ native_run_local_return_jvoid()@endlink.
+ * </li>
+ * <li> for a @link #jvm_object_hash jobject@endlink functions, add
+ * the ordinal number to @link
+ #native_run_local_return_jobject()
+ native_run_local_return_jobject()@endlink.
+ * </li>
+ * <li> for a @link #jbyte jbyte@endlink functions, add the ordinal
+ * number to @link #native_run_local_return_jint()
+ native_run_local_return_jint()@endlink.
+ * </li>
+ * <li> for a @link #jboolean jboolean@endlink functions, add the
+ * ordinal number to @link #native_run_local_return_jint()
+ native_run_local_return_jint()@endlink.
+ * </li>
+ * <li> for a @link #jshort jshort@endlink functions, add the
+ * ordinal number to @link #native_run_local_return_jint()
+ native_run_local_return_jint()@endlink.
+ * </li>
+ * <li> for a @link #jchar jchar@endlink functions, add the ordinal
+ * number to @link #native_run_local_return_jint()
+ native_run_local_return_jint()@endlink.
+ * </li>
+ * <li> for a @link #jshort jshort@endlink functions, add the
+ * ordinal number to @link #native_run_local_return_jint()
+ native_run_local_return_jint()@endlink.
+ * </li>
+ * <li> for a @link #jint jint@endlink functions, add the ordinal
+ * number to @link #native_run_local_return_jint()
+ native_run_local_return_jint()@endlink.
+ * </li>
+ * <li> for a @link #jfloat jfloat@endlink functions, add the
+ * ordinal number to @link #native_run_local_return_jfloat()
+ native_run_local_return_jfloat()@endlink.
+ * </li>
+ * <li> for a @link #jlong jlong@endlink functions, add the ordinal
+ * number to @link #native_run_local_return_jlong()
+ native_run_local_return_jlong()@endlink.
+ * </li>
+ * <li> for a @link #jdouble jdouble@endlink functions, add the
+ * ordinal number to @link #native_run_local_return_jdouble()
+ native_run_local_return_jdouble()@endlink.
+ * </li>
+ * </ul>
+ * </li>
+ * </ul>
+ *
+ * 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
+ * @c @b 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 @b NewClassType files once they are written:
+ *
+ * <ul>
+ * <li> Add the JVM core header file declaration to the header file
+ * area. Be sure to @e also add documentation tags for proper
+ * visibility to this documentation suite.
+ *
+ * @verbatim
+ #define JLNEWCLASSTYPE_LOCAL_DEFINED
+ #include "jlNewClassType.h"
+
+ @endverbatim
+ * </li>
+ * <li> Add a reference to NATIVE_TABLE_JLNEWCLASSTYPE
+ to the case statement in
+ * @link #native_verify_ordinal_definition()
+ native_verify_ordinal_definition()@endlink.
+ * </li>
+ * <li> Add the entry,
+ *
+ * @verbatim
+ {JVMCLASS_JAVA_LANG_NEWCLASSTYPE,
+ NATIVE_TABLE_JLNEWCLASSTYPE_ORDINALS },
+
+ @endverbatim
+ * to the @link #native_local_method_list
+ to native_local_method_list[]@endlink table.
+ * </li>
+ * <li> Add the following macro references to the appropriate
+ * locations in @link #native_run_method()
+ native_run_method()@endlink, based on return type:
+ *
+ * <ul>
+ * <li> @b NATIVE_TABLE_JLNEWCLASSTYPE_JVOID </li>
+ * <li> @b NATIVE_TABLE_JLNEWCLASSTYPE_JOBJECT </li>
+ * <li> @b NATIVE_TABLE_JLNEWCLASSTYPE_JINT </li>
+ * <li> @b NATIVE_TABLE_JLNEWCLASSTYPE_JFLOAT </li>
+ * <li> @b NATIVE_TABLE_JLNEWCLASSTYPE_JLONG </li>
+ * <li> @b NATIVE_TABLE_JLNEWCLASSTYPE_JDOUBLE </li>
+ * </ul>
+ * </li>
+ * </ul>
+ *
+ * This completes the JNI interconnection process.
+ *
+ *
+ * @section Control
+ *
+ * \$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.
+ *
+ * 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.
+ *
+ * @version \$LastChangedRevision: 0 $
+ *
+ * @date \$LastChangedDate: 09/28/2005 $
+ *
+ * @author \$LastChangedBy: dlydick $
+ * Original code contributed by Daniel Lydick on 09/28/2005.
+ *
+ * @section Reference
+ *
+ */
+
+#include "arch.h"
+ARCH_COPYRIGHT_APACHE(native, c, "$URL: https://svn.apache.org/path/name/native.c $ $Id: native.c 0 09/28/2005 dlydick $");
+
+#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 ALL local native class header files here: */
+
+/*!
+ * @brief Local implementation mode inclusion of
+ * @link jvm/include/jlObject.h jlObject.h@endlink
+ */
+#define JLOBJECT_LOCAL_DEFINED
+#include "jlObject.h"
+
+/*!
+ * @brief Local implementation mode inclusion of
+ * @link jvm/include/jlClass.h jlClass.h@endlink
+ */
+#define JLCLASS_LOCAL_DEFINED
+#include "jlClass.h"
+
+/*!
+ * @brief Local implementation mode inclusion of
+ * @link jvm/include/jlString.h jlString.h@endlink
+ */
+#define JLSTRING_LOCAL_DEFINED
+#include "jlString.h"
+
+/*!
+ * @brief Local implementation mode inclusion of
+ * @link jvm/include/jlThread.h jlThread.h@endlink
+ */
+#define JLTHREAD_LOCAL_DEFINED
+#include "jlThread.h"
+
+
+/*!
+ * @name Real machine automatic local variable stack frame conversion.
+ *
+ * @brief List of real machine local variables used as scratchpad
+ * for the several @link POP_JINT() POP_xxx()@endlink
+ * 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.
+ *
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+#define POP_SCRATCHPAD_JVM \
+ jvm_class_index clsidxCURR; \
+ jvm_object_hash objhashTHIS
+
+#define POP_SCRATCHPAD_JOBJECT \
+ jint joparm
+
+#define POP_SCRATCHPAD_JINT \
+ jint jiparm
+
+#define POP_SCRATCHPAD_JFLOAT \
+ jint jfparm
+
+#define POP_SCRATCHPAD_JLONG \
+ jlong jlparm; \
+ jint jlpms; \
+ jint jlpls
+
+#define POP_SCRATCHPAD_JDOUBLE \
+ jint jdparm; \
+ jint jlpms; \
+ jint jlpls
+
+/*@} */ /* End of grouped definitions */
+
+
+/*!
+ * @name JVM stack frame access for local native method interface.
+ *
+ * @brief 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.
+ *
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+
+/*!
+ * @brief Retrieve current class index parameter from the top of
+ * the JVM stack into real machine local variable @b clsidxCURR
+ * for use as a parameter to local native @c @b static
+ * method calls.
+ *
+ *
+ * @param thridx Thead index of stack to access.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ */
+#define GET_CURRENT_CLSIDX(thridx) \
+ GET_PC_FIELD(thridx, clsidxCURR, clsidx)
+
+
+/*!
+ * @brief Retrieve @c @b this object hash parameter from the
+ * top of the JVM stack into real machine local variable @b objhashTHIS
+ * for use as a parameter to local native object instance method calls.
+ *
+ *
+ * @param thridx Thead index of stack to access.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ */
+#define POP_THIS_OBJHASH(thridx) \
+ POP(thridx, objhashTHIS, jvm_object_hash)
+
+
+/*!
+ * @brief Retrieve a (jobject) method parameter from the top of
+ * the JVM stack into real machine local variable @b joparm
+ * for use as a parameter to local native method calls.
+ *
+ *
+ * @param thridx Thead index of stack to access.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ */
+#define POP_JOBJECT(thridx) \
+ POP(thridx, joparm, jvm_object_hash)
+
+
+/*!
+ * @brief Retrieve a (jint) method parameter from the top of
+ * the JVM stack into real machine local variable @b jiparm
+ * for use as a parameter to local native method calls.
+ *
+ *
+ * @param thridx Thead index of stack to access.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ */
+#define POP_JINT(thridx) \
+ POP(thridx, jiparm, jint)
+
+
+/*!
+ * @brief Retrieve a (jfloat) method parameter from the top of
+ * the JVM stack into real machine local variable @b jfparm
+ * for use as a parameter to local native method calls.
+ *
+ *
+ * @param thridx Thead index of stack to access.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ * @todo Perform value set conversion here for native methods
+ * and elsewhere for virtual methods.
+ *
+ */
+#define POP_JFLOAT(thridx) \
+ POP(thridx, jfparm, jfloat)
+
+
+/*!
+ * @brief Retrieve a (jlong) method parameter from the top of
+ * the JVM stack into real machine local variable @b jlparm
+ * for use as a parameter to local native method calls.
+ *
+ *
+ * @param thridx Thead index of stack to access.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ */
+#define POP_JLONG(thridx) \
+ POP(thridx, jlpls, jint); \
+ POP(thridx, jlpms, jint); \
+ jlparm = bytegames_combine_jlong(jlpms, jlpls)
+
+
+/*!
+ * @brief Retrieve a (jdouble) method parameter from the top of
+ * the JVM stack into real machine local variable @b jdparm
+ * for use as a parameter to local native method calls.
+ *
+ *
+ * @param thridx Thead index of stack to access.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ * @todo Perform value set conversion here for native methods
+ * and elsewhere for virtual methods.
+ *
+ */
+#define POP_JDOUBLE(thridx) \
+ POP(thridx, jlpls, jint); \
+ POP(thridx, jlpms, jint); \
+ jdparm = bytegames_combine_jdouble(jlpms, jlpls)
+
+/*@} */ /* End of grouped definitions */
+
+
+/*!
+ * @name Local native method interface.
+ *
+ * @brief Map JVM stack frame to real machine native method
+ * implementation, invoke the actual real function, and
+ * report the results.
+ *
+ *
+ * @param nmord Ordinal number definition of local native method.
+ *
+ * @param thridx JVM thread where request came from.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+/*!
+ * @brief Local native equivalent of
+ * <b><code>native void mthname()</code></b>
+ *
+ * The JVM returns from a @c @b void method
+ * using the @b RETURN opcode.
+ *
+ */
+static
+ rvoid native_run_local_return_jvoid(jvm_native_method_ordinal nmord,
+ jvm_thread_index thridx)
+{
+ POP_SCRATCHPAD_JVM;
+ POP_SCRATCHPAD_JINT;
+ POP_SCRATCHPAD_JLONG;
+
+ switch((int) nmord)
+ {
+ case JLOBJECT_NMO_WAIT4EVER:
+ POP_THIS_OBJHASH(thridx);
+
+ jlObject_wait4ever(objhashTHIS);
+ break;
+
+ case JLOBJECT_NMO_WAITTIMED:
+ POP_JLONG(thridx);
+ POP_THIS_OBJHASH(thridx);
+
+ jlObject_waittimed(objhashTHIS, jlparm);
+ break;
+
+ case JLTHREAD_NMO_YIELD:
+ GET_CURRENT_CLSIDX(thridx);
+
+ jlThread_yield(clsidxCURR);
+ break;
+
+ case JLTHREAD_NMO_INTERRUPT:
+ POP_THIS_OBJHASH(thridx);
+
+ jlThread_interrupt(objhashTHIS);
+ break;
+
+ case JLTHREAD_NMO_JOIN4EVER:
+ POP_THIS_OBJHASH(thridx);
+
+ jlThread_join4ever(objhashTHIS);
+ break;
+
+ case JLTHREAD_NMO_JOINTIMED:
+ POP_JLONG(thridx);
+ POP_THIS_OBJHASH(thridx);
+
+ jlThread_jointimed(objhashTHIS, jlparm);
+ break;
+
+ case JLTHREAD_NMO_JOINTIMED_NANOS:
+ POP_JINT(thridx);
+ POP_JLONG(thridx);
+ POP_THIS_OBJHASH(thridx);
+
+ jlThread_jointimed_nanos(objhashTHIS, jlparm, jiparm);
+ break;
+
+ case JLTHREAD_NMO_SETDAEMON:
+ POP_JINT(thridx);
+ POP_THIS_OBJHASH(thridx);
+
+ jlThread_setDaemon(objhashTHIS, (jboolean) jiparm);
+ break;
+
+ case JLTHREAD_NMO_STOP:
+ POP_THIS_OBJHASH(thridx);
+
+ jlThread_stop(objhashTHIS);
+ break;
+
+ case JLTHREAD_NMO_SUSPEND:
+ POP_THIS_OBJHASH(thridx);
+
+ jlThread_suspend(objhashTHIS);
+ break;
+
+ case JLTHREAD_NMO_RESUME:
+ POP_THIS_OBJHASH(thridx);
+
+ jlThread_resume(objhashTHIS);
+ break;
+
+ /* case JVMCFG_JLOBJECT_NMO_NULL: */
+ default:
+ exit_throw_exception(EXIT_JVM_INTERNAL,
+ JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
+/*NOTREACHED*/
+ }
+
+ /* No data to pass back, so just leave */
+ return;
+
+} /* END of native_run_local_return_jvoid() */
+
+
+/*!
+ * @brief Local native equivalent of
+ * <b><code>native jobject mthname()</code></b>
+ *
+ * The JVM returns from a @c @b jobject method
+ * using the @b ARETURN opcode.
+ *
+ */
+static jvm_object_hash
+ native_run_local_return_jobject(jvm_native_method_ordinal nmord,
+ jvm_thread_index thridx)
+{
+ jvm_object_hash rc;
+
+ POP_SCRATCHPAD_JVM;
+
+ switch(nmord)
+ {
+ case JLOBJECT_NMO_GETCLASS:
+ POP_THIS_OBJHASH(thridx);
+
+ rc = jlObject_getClass(objhashTHIS);
+ break;
+
+ case JLTHREAD_NMO_CURRENTTHREAD:
+ GET_CURRENT_CLSIDX(thridx);
+
+ rc = jlThread_currentThread(clsidxCURR);
+ break;
+
+ case JVMCFG_JLOBJECT_NMO_NULL:
+ default:
+ exit_throw_exception(EXIT_JVM_INTERNAL,
+ JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
+/*NOTREACHED*/
+ }
+
+ /* Store result back into JVM stack frame of invoker */
+ PUSH(thridx, rc);
+
+ /* Also return result to caller */
+ return(rc);
+
+} /* END of native_run_local_return_jobject() */
+
+
+/*!
+ * @brief Local native equivalent of
+ * <b><code>native int mthname()</code></b>, also used for
+ * @c @b (boolean), @c @b (byte), @c @b (char),
+ * and @c @b (short) return types.
+ *
+ * The JVM returns from a @c @b int method (and those of
+ * the listed sub-integer return types) using the @b IRETURN opcode.
+ *
+ */
+static
+ jint native_run_local_return_jint(jvm_native_method_ordinal nmord,
+ jvm_thread_index thridx)
+{
+ jint rc;
+
+ POP_SCRATCHPAD_JVM;
+ POP_SCRATCHPAD_JOBJECT;
+ POP_SCRATCHPAD_JINT;
+ POP_SCRATCHPAD_JLONG;
+
+ switch(nmord)
+ {
+ case JLOBJECT_NMO_HASHCODE:
+ POP_THIS_OBJHASH(thridx);
+
+ rc = jlObject_hashCode(objhashTHIS);
+ break;
+
+ case JLCLASS_NMO_ISARRAY:
+ POP_THIS_OBJHASH(thridx);
+
+ rc = jlClass_isArray(objhashTHIS);
+ break;
+
+ case JLCLASS_NMO_ISPRIMATIVE:
+ POP_THIS_OBJHASH(thridx);
+
+ rc = jlClass_isPrimative(objhashTHIS);
+ break;
+
+ case JLTHREAD_NMO_INTERRUPTED:
+ GET_CURRENT_CLSIDX(thridx);
+
+ rc = jlThread_interrupted(clsidxCURR);
+ break;
+
+ case JLTHREAD_NMO_ISINTERRUPTED:
+ POP_THIS_OBJHASH(thridx);
+
+ rc = jlThread_isInterrupted(objhashTHIS);
+ break;
+
+ case JLTHREAD_NMO_SLEEP:
+ POP_JLONG(thridx);
+ GET_CURRENT_CLSIDX(thridx);
+
+ rc = jlThread_sleep(clsidxCURR, jlparm);
+ break;
+
+ case JLTHREAD_NMO_SLEEP_NANOS:
+ POP_JINT(thridx);
+ POP_JLONG(thridx);
+ GET_CURRENT_CLSIDX(thridx);
+
+ rc = jlThread_sleep_nanos(clsidxCURR, jlparm, jiparm);
+ break;
+
+ case JLTHREAD_NMO_ISALIVE:
+ POP_THIS_OBJHASH(thridx);
+
+ rc = (jint) jlThread_isAlive(objhashTHIS);
+ break;
+
+ case JLTHREAD_NMO_START:
+ POP_THIS_OBJHASH(thridx);
+
+ rc = (jint) jlThread_start(objhashTHIS);
+ break;
+
+ case JLTHREAD_NMO_COUNTSTACKFRAMES:
+ POP_THIS_OBJHASH(thridx);
+
+ rc = jlThread_countStackFrames(objhashTHIS);
+ break;
+
+ case JLTHREAD_NMO_HOLDSLOCK:
+ POP_JOBJECT(thridx);
+ GET_CURRENT_CLSIDX(thridx);
+
+ rc = (jint) jlThread_holdsLock(objhashTHIS, joparm);
+ break;
+
+ case JLTHREAD_NMO_SETPRIORITY:
+ POP_JINT(thridx);
+ POP_THIS_OBJHASH(thridx);
+
+ rc = (jint)
+ jlThread_setPriority(objhashTHIS, jiparm);
+ break;
+
+ case JLTHREAD_NMO_GETPRIORITY:
+ POP_THIS_OBJHASH(thridx);
+
+ rc = jlThread_getPriority(objhashTHIS);
+ break;
+
+ case JLTHREAD_NMO_DESTROY:
+ POP_THIS_OBJHASH(thridx);
+
+ rc = (jint) jlThread_destroy(objhashTHIS);
+ break;
+
+ case JLTHREAD_NMO_CHECKACCESS:
+ POP_THIS_OBJHASH(thridx);
+
+ rc = (jint) jlThread_checkAccess(objhashTHIS);
+ break;
+
+ case JLTHREAD_NMO_ISDAEMON:
+ POP_THIS_OBJHASH(thridx);
+
+ rc = (jint) jlThread_isDaemon(objhashTHIS);
+ break;
+
+ case JVMCFG_JLOBJECT_NMO_NULL:
+ default:
+ exit_throw_exception(EXIT_JVM_INTERNAL,
+ JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
+/*NOTREACHED*/
+ }
+
+ /* Store result back into JVM stack frame of invoker */
+ PUSH(thridx, rc);
+
+ /* Also return result to caller */
+ return(rc);
+
+} /* END of native_run_local_return_jint() */
+
+
+/*!
+ * @brief Local native equivalent of
+ * <b><code>native float mthname()</code></b>
+ *
+ * The JVM returns from a @c @b float method
+ * using the @b FRETURN opcode.
+ *
+ */
+static jfloat
+ native_run_local_return_jfloat(jvm_native_method_ordinal nmord,
+ jvm_thread_index thridx)
+{
+ jfloat rc;
+
+ /* POP_SCRATCHPAD_JVM; */
+
+ switch(nmord)
+ {
+ case JVMCFG_JLOBJECT_NMO_NULL:
+ default:
+ exit_throw_exception(EXIT_JVM_INTERNAL,
+ JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
+/*NOTREACHED*/
+ }
+
+ /* Store result back into JVM stack frame of invoker */
+ PUSH(thridx, rc);
+
+ /* Also return result to caller */
+ return(rc);
+
+} /* END of native_run_local_return_jfloat() */
+
+
+/*!
+ * @brief Local native equivalent of
+ * <b><code>native long mthname()</code></b>
+ *
+ * The JVM returns from a @c @b long method
+ * using the @b LRETURN opcode.
+ *
+ */
+static
+ jlong native_run_local_return_jlong(jvm_native_method_ordinal nmord,
+ jvm_thread_index thridx)
+{
+ jlong rc;
+ jint rcms, rcls;
+
+ /* POP_SCRATCHPAD_JVM; */
+
+ switch(nmord)
+ {
+ case JVMCFG_JLOBJECT_NMO_NULL:
+ default:
+ exit_throw_exception(EXIT_JVM_INTERNAL,
+ JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
+/*NOTREACHED*/
+ }
+
+ /* Store result back into JVM stack frame of invoker */
+
+ bytegames_split_jlong(rc, &rcms, &rcls);
+
+ PUSH(thridx, rcms);
+ PUSH(thridx, rcls);
+
+ /* Also return result to caller */
+ return(rc);
+
+} /* END of native_run_local_return_jlong() */
+
+
+/*!
+ * @brief Local native equivalent of
+ * <b><code>native double mthname()</code></b>
+ *
+ * The JVM returns from a @c @b double method
+ * using the @b DRETURN opcode.
+ *
+ */
+static jdouble
+ native_run_local_return_jdouble(jvm_native_method_ordinal nmord,
+ jvm_thread_index thridx)
+{
+ jdouble rc;
+ jint rcms, rcls;
+
+ /* POP_SCRATCHPAD_JVM */;
+
+ switch(nmord)
+ {
+ case JVMCFG_JLOBJECT_NMO_NULL:
+ default:
+ exit_throw_exception(EXIT_JVM_INTERNAL,
+ JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
+/*NOTREACHED*/
+ }
+
+ /* Store result back into JVM stack frame of invoker */
+
+ bytegames_split_jdouble(rc, &rcms, &rcls);
+
+ PUSH(thridx, rcms);
+ PUSH(thridx, rcls);
+
+ /* Also return result to caller */
+ return(rc);
+
+} /* END of native_run_local_return_jdouble() */
+
+/*@} */ /* End of grouped definitions */
+
+
+/*!
+ * @brief Verify the validity of a native method ordinal number.
+ *
+ * The purpose of this function is to verify that @e all of the
+ * ordinal numbers are listed in the @c @b switch statement
+ * here and are unique and complete for all defined local native
+ * methods.
+ *
+ * @internal Although this function is invoked from
+ * @link #native_locate_local_method()
+ native_locate_local_method()@endlink, 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.
+ *
+ *
+ * @param nmord Ordinal number definition of local native method.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink if found, else throws an error.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR
+ * @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+ * if ordinal number of local native method
+ * was not found.@endlink.
+ *
+ */
+
+static rvoid native_verify_ordinal_definition(
+ jvm_native_method_ordinal nmord)
+{
+ switch(nmord)
+ {
+ /*
+ * Add @b NATIVE_TABLE_JLxxx entries
+ * here @b WITHOUT colon (:) characters...
+ */
+ NATIVE_TABLE_JLOBJECT
+ NATIVE_TABLE_JLCLASS
+ NATIVE_TABLE_JLSTRING
+ NATIVE_TABLE_JLTHREAD
+
+ /*
+ * All classes use the same register/unregister ordinals
+ */
+ case JVMCFG_JLOBJECT_NMO_REGISTER:
+ case JVMCFG_JLOBJECT_NMO_UNREGISTER:
+ return;
+
+ case JVMCFG_JLOBJECT_NMO_NULL:
+ default:
+ exit_throw_exception(EXIT_JVM_INTERNAL,
+ JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
+/*NOTREACHED*/
+ }
+
+} /* END of native_verify_ordinal_definition() */
+
+
+/*!
+ * @name Native local method mapping structures
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+/*!
+ * @brief 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
+ * @link #native_local_method_list native_local_method_list[]@endlink
+ * 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.)
+ *
+ */
+#define NLML_MAX_CLASSES 5
+
+
+/*!
+ * @brief 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
+ * @link #native_local_method_map.nlmo_map
+ * native_local_method_list.nlmo_map@endlink and then increase
+ * the value so that just the right number of elements are
+ * allocated for the largest class.
+ *
+ */
+#define NLMO_MAX_SLOTS 25
+
+
+/*!
+ * @brief Associate a local native method ordinal number
+ * with its JVM method name and description string.
+ *
+ * This table gathers all of the @link #NATIVE_TABLE_JLOBJECT_ORDINALS
+ NATIVE_TABLE_JLxxxxxx_ORDINALS@endlink definitions from the
+ * @link jvm/src/jlObject.c jlXxxxx.c@endlink JNI local method
+ * interface source files for reference in this code.
+ */
+
+typedef struct
+{
+ /*! Ordinal number for this method */
+ jvm_native_method_ordinal nmord;
+
+ /*! Null-terminated string name of method */
+ rchar *mthname;
+
+ /*! Null-terminated string description of method */
+ rchar *mthdesc;
+
+} native_local_method_ordinal_map;
+
+
+/*!
+ * @brief Associate a class name with its local native method
+ * ordinal numbers and its JVM method name and description
+ * strings.
+ *
+ * This table gathers all of the @link #NATIVE_TABLE_JLOBJECT_ORDINALS
+ NATIVE_TABLE_JLxxxxxx_ORDINALS@endlink definitions from the
+ * @link jvm/src/jlObject.c jlXxxxx.c@endlink JNI local method
+ * interface source files for reference in this code.
+ */
+typedef struct
+{
+ /*! Null-terminated class name string */
+ rchar *clsname;
+
+ /*! Associate this class with a list of
+ local native methods that are implemented
+ in this class */
+
+ native_local_method_ordinal_map nlmo_map[NLMO_MAX_SLOTS];
+
+} native_local_method_map;
+
+
+/*!
+ * @brief Complete and authoritative list of Java classes implementing
+ * local native methods. Each @link jvm/include/jlObject.h
+ jlXxxxx.h@endlink header file defines a suite of
+ * @link #NATIVE_TABLE_JLOBJECT_ORDINALS
+ NATIVE_TABLE_JLxxxxx_ORDINALS@endlink. This suite is entered
+ * here for processing by the local native method logic.
+ *
+ * @see jvm/include/jlClass.h
+ *
+ * @see jvm/include/jlObject.h
+ *
+ * @see jvm/include/jlString.h
+ *
+ * @see jvm/include/jlThread.h
+ *
+ */
+native_local_method_map native_local_method_list[NLML_MAX_CLASSES] =
+{
+ {JVMCLASS_JAVA_LANG_OBJECT, NATIVE_TABLE_JLOBJECT_ORDINALS },
+ {JVMCLASS_JAVA_LANG_CLASS, NATIVE_TABLE_JLCLASS_ORDINALS },
+ {JVMCLASS_JAVA_LANG_STRING, NATIVE_TABLE_JLSTRING_ORDINALS },
+ {JVMCLASS_JAVA_LANG_THREAD, NATIVE_TABLE_JLTHREAD_ORDINALS },
+
+ /*
+ * Add more classes here
+ */
+
+
+ /* End of table marker, regardless of static array[size] */
+ {
+ CHEAT_AND_USE_NULL_TO_INITIALIZE,
+ {
+ {
+ JVMCFG_JLOBJECT_NMO_NULL,
+ CHEAT_AND_USE_NULL_TO_INITIALIZE,
+ CHEAT_AND_USE_NULL_TO_INITIALIZE
+ }
+ }
+ }
+};
+
+/*@} */ /* End of grouped definitions */
+
+
+/*!
+ * @brief Associate class name string with its local native
+ * method interface connection.
+ *
+ *
+ * @param pcfs ClassFile pointer of a class referencing a
+ * native method, local or otherwise. The following
+ * constant_pool indices are all relative to this
+ * ClassFile.
+ *
+ * @param clsnameidx constant_pool index in @b pcfs of class name to
+ * locate in class table.
+ *
+ * @param mthnameidx constant_pool index in @b pcfs of method name to
+ * locate in @b clsnameidx.
+ *
+ * @param mthdescidx constant_pool index in @b pcfs of method
+ * description with method name @b mthnameidx
+ * to locate in @b clsnameidx.
+ *
+ * @param find_registerNatives When @link #rtrue rtrue@endlink,
+ * will return the ordinal for
+ * @link #JVMCFG_JLOBJECT_NMO_REGISTER
+ JVMCFG_JLOBJECT_NMO_REGISTER@endlink and
+ * @link #JVMCFG_JLOBJECT_NMO_UNREGISTER
+ JVMCFG_JLOBJECT_NMO_UNREGISTER@endlink
+ * as well as the other ordinals. Once JVM
+ * initialization is complete, this should always
+ * be @link #rfalse rfalse@endlink because
+ * all future classes should
+ * @e never have local ordinals.
+ *
+ *
+ * @returns ordinal definition for this method, or @link
+ #jvm_native_method_ordinal_null
+ jvm_native_method_ordinal_null@endlink if not found.
+ *
+ */
+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)
+{
+ rint nmoclsnameidx;
+ rint nmomthnameidx;
+
+ for (nmoclsnameidx= 0;
+ rnull != native_local_method_list[nmoclsnameidx].clsname;
+ nmoclsnameidx++)
+ {
+ if (0 == utf_prchar_pcfs_strcmp(
+ native_local_method_list[nmoclsnameidx].clsname,
+ pcfs,
+ clsnameidx))
+ {
+ for (nmomthnameidx= 0;
+ jvm_native_method_ordinal_null !=
+ native_local_method_list[nmoclsnameidx]
+ .nlmo_map[nmomthnameidx]
+ .nmord;
+ nmomthnameidx++)
+ {
+ if (0 == utf_prchar_pcfs_strcmp(
+ native_local_method_list[nmoclsnameidx]
+ .nlmo_map[nmomthnameidx]
+ .mthname,
+ pcfs,
+ mthnameidx))
+ {
+ if (0 == utf_prchar_pcfs_strcmp(
+ native_local_method_list[nmoclsnameidx]
+ .nlmo_map[nmomthnameidx]
+ .mthdesc,
+ pcfs,
+ mthdescidx))
+ {
+ return(native_local_method_list[nmoclsnameidx]
+ .nlmo_map[nmomthnameidx]
+ .nmord);
+ }
+ }
+ }
+ }
+ }
+
+ if (rtrue == find_registerNatives)
+ {
+ /* Check two special cases, register/unregister native methods*/
+ if (0 == utf_prchar_pcfs_strcmp(JVMCFG_REGISTER_NATIVES_METHOD,
+ pcfs,
+ mthnameidx))
+ {
+ if (0 ==
+ utf_prchar_pcfs_strcmp(JVMCFG_REGISTER_NATIVES_PARMS,
+ pcfs,
+ mthdescidx))
+ {
+ return(JVMCFG_JLOBJECT_NMO_REGISTER);
+ }
+ }
+
+ if (0 ==
+ utf_prchar_pcfs_strcmp(JVMCFG_UNREGISTER_NATIVES_METHOD,
+ pcfs,
+ mthnameidx))
+ {
+ if (0 ==
+ utf_prchar_pcfs_strcmp(JVMCFG_UNREGISTER_NATIVES_PARMS,
+ pcfs,
+ mthdescidx))
+ {
+ return(JVMCFG_JLOBJECT_NMO_UNREGISTER);
+ }
+ }
+ }
+
+ /* Not found */
+ return(jvm_native_method_ordinal_null);
+
+} /* END of native_locate_local_method() */
+
+
+/*!
+ * @brief 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
+ * @link #JLOBJECT_NMO_NULL JLOBJECT_NMO_NULL@endlink ordinal and with
+ * normal class and method information.
+ *
+ * @attention A necessary restriction of this local native method
+ * interface is that the real machine functions that
+ * are called as Java native methods <em>MAY NOT</em>
+ * attempt to call Java virtual functions. Code that
+ * needs to do this should use the full JNI instead.
+ * The same is true about Java-domain access to data.
+ * As a practical matter, this should never be an issue
+ * because the suite of local native methods is concerned
+ * with JVM core internals, that is, in the real machine
+ * domain, and will probably never care about Java-domain
+ * functionality.
+ *
+ * @attention All local native methods @e must throw @b Errors through
+ * @link
+ #exit_throw_exception() exit_throw_exception()@endlink
+ * so as to avoid crossing from real- to Java-domain
+ * functionality. Each and every possible subclass of
+ * @c @b java.lang.Error and every possible subclass
+ * of @c @b java.lang.Exception is available through
+ * this interface. It will be loaded and an instance created
+ * in the usual manner after being thrown by the native
+ * code through this function. The result, of course, is
+ * a normal state of the JVM, which will be shut down
+ * in the normal fashion for @b Errors, but will only
+ * stop the thread for @b Exceptions.
+ *
+ * @param thridx JVM thread where request came from.
+ *
+ * @param nmord Ordinal number definition of local native method.
+ *
+ * @param clsidx Class table index of native method to invoke.
+ *
+ * @param mthnameidx Class file constant_pool index of name of native
+ * method to invoke. This entry must be a
+ * CONSTANT_Utf8_info string containing an
+ * unqualified method name.
+ *
+ * @param mthdescidx Class file constant_pool index of descriptor of
+ * method to invoke. This entry must be a
+ * CONSTANT_Utf8_info string containing the
+ * descriptor of an unqualified method name.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink. May throw an error or
+ * exception of @e any kind from with the native code.
+ *
+ */
+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)
+{
+ /*!
+ * Verify that this local native method ordinal is both
+ * unique and complete.
+ */
+ native_verify_ordinal_definition(nmord);
+
+ switch(nmord)
+ {
+ /*!
+ * Invoke JNI methods, not local native methods
+ */
+ case JVMCFG_JLOBJECT_NMO_NULL:
+ /*!
+ * @todo Invoke the full JNI interface for this method at
+ * this place. Additional parameters will be needed.
+ *
+ * Currently, the JNI interface is stubbed out here.
+ * The implementation goes something like this:
+ *
+ * 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 @c @b dlopen(3), @c @b dlsym(3),
+ * etc. Recommend adding function
+ * method_load_jni_lib() in this source file
+ * for this purpose.)
+ *
+ * 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 @e first item pushed has the
+ * lowest real machine address. Many stacks are a
+ * push-DOWN type, which means that the @e 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.
+ *
+ */
+ if (rfalse == JVMCFG_IGNORE_NATIVE_METHOD_CALLS)
+ {
+ exit_throw_exception(EXIT_JVM_METHOD,
+ JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
+/*NOTREACHED*/
+ }
+
+ jvalue rc;
+ jint rcms, rcls;
+
+ switch (method_return_type(clsidx, mthdescidx))
+ {
+ case BASETYPE_CHAR_B:
+ case BASETYPE_CHAR_C:
+ case BASETYPE_CHAR_I:
+ case BASETYPE_CHAR_S:
+ case BASETYPE_CHAR_Z:
+ rc._jint = 0;
+ PUSH(thridx, rc._jint);
+ return;
+
+ case BASETYPE_CHAR_J:
+ rc._jlong = 0;
+ bytegames_split_jlong(rc._jlong, &rcms, &rcls);
+ PUSH(thridx, rcms);
+ PUSH(thridx, rcls);
+ return;
+
+ case BASETYPE_CHAR_L:
+ rc._jobjhash = jvm_object_hash_null;
+ PUSH(thridx, rc._jobjhash);
+ return;
+
+ case BASETYPE_CHAR_D:
+ rc._jdouble = 0.0;
+ bytegames_split_jdouble(rc._jdouble, &rcms, &rcls);
+ PUSH(thridx, rcms);
+ PUSH(thridx, rcls);
+ return;
+
+ case BASETYPE_CHAR_F:
+ rc._jfloat = 0.0;
+ PUSH(thridx, rc._jfloat);
+ return;
+
+ case BASETYPE_CHAR_ARRAY:
+ rc._jarray = jvm_object_hash_null;
+ PUSH(thridx, rc._jarray);
+ return;
+
+ case METHOD_CHAR_VOID:
+ return;
+
+ default:
+ /*!
+ * @todo Which is the better error, @b VerifyError
+ * or @b NoSuchMethodError ?
+ */
+ exit_throw_exception(EXIT_JVM_METHOD,
+ JVMCLASS_JAVA_LANG_VERIFYERROR);
+/*NOTREACHED*/
+ return; /* Satisfy compiler */
+ }
+
+ return; /* Satisfy compiler */
+
+ /*!
+ * Invoke local native methods that return (jvoid)
+ */
+ NATIVE_TABLE_JLOBJECT_JVOID
+ NATIVE_TABLE_JLCLASS_JVOID
+ NATIVE_TABLE_JLSTRING_JVOID
+ NATIVE_TABLE_JLTHREAD_JVOID
+
+ /*
+ * Add @b NATIVE_TABLE_JLxxxx_JVOID entries
+ * here @b WITHOUT colon (:) characters...
+ */
+
+
+ /* (rvoid) ... obviously redundant */
+ native_run_local_return_jvoid(nmord, thridx);
+ return;
+
+ /*!
+ * Invoke local native methods that return (jobject),
+ * known to this implementation as (jvm_object_hash).
+ */
+ NATIVE_TABLE_JLOBJECT_JOBJECT
+ NATIVE_TABLE_JLCLASS_JOBJECT
+ NATIVE_TABLE_JLSTRING_JOBJECT
+ NATIVE_TABLE_JLTHREAD_JOBJECT
+
+ /*
+ * Add @b NATIVE_TABLE_JLxxxx_JOBJECT entries
+ * here @b WITHOUT colon (:) characters...
+ */
+
+
+ (rvoid) native_run_local_return_jobject(nmord, thridx);
+ return;
+
+ /*!
+ * Invoke local native methods that return (jint)
+ */
+ NATIVE_TABLE_JLOBJECT_JINT
+ NATIVE_TABLE_JLCLASS_JINT
+ NATIVE_TABLE_JLSTRING_JINT
+ NATIVE_TABLE_JLTHREAD_JINT
+
+ /*
+ * Add @b NATIVE_TABLE_JLxxxx_JINT entries
+ * here @b WITHOUT colon (:) characters...
+ */
+
+
+ (rvoid) native_run_local_return_jint(nmord, thridx);
+ return;
+
+ /*!
+ * Invoke local native methods that return (jfloat)
+ */
+ NATIVE_TABLE_JLOBJECT_JFLOAT
+ NATIVE_TABLE_JLCLASS_JFLOAT
+ NATIVE_TABLE_JLSTRING_JFLOAT
+ NATIVE_TABLE_JLTHREAD_JFLOAT
+
+ /*
+ * Add @b NATIVE_TABLE_JLxxxx_JFLOAT entries
+ * here @b WITHOUT colon (:) characters...
+ */
+
+
+ (rvoid) native_run_local_return_jfloat(nmord, thridx);
+ return;
+
+ /*!
+ * Invoke local native methods that return (jlong)
+ */
+ NATIVE_TABLE_JLOBJECT_JLONG
+ NATIVE_TABLE_JLCLASS_JLONG
+ NATIVE_TABLE_JLSTRING_JLONG
+ NATIVE_TABLE_JLTHREAD_JLONG
+
+ /*
+ * Add @b NATIVE_TABLE_JLxxxx_JLONG entries
+ * here @b WITHOUT colon (:) characters...
+ */
+
+
+ (rvoid) native_run_local_return_jlong(nmord, thridx);
+ return;
+
+ /*!
+ * Invoke local native methods that return (jdouble)
+ */
+ NATIVE_TABLE_JLOBJECT_JDOUBLE
+ NATIVE_TABLE_JLCLASS_JDOUBLE
+ NATIVE_TABLE_JLSTRING_JDOUBLE
+ NATIVE_TABLE_JLTHREAD_JDOUBLE
+
+ /*
+ * Add @b NATIVE_TABLE_JLxxxx_JDOUBLE entries
+ * here @b WITHOUT colon (:) characters...
+ */
+
+
+ (rvoid) native_run_local_return_jdouble(nmord, thridx);
+ return;
+
+
+ /*!
+ * IGNORE local native method registration.
+ */
+ case JVMCFG_JLOBJECT_NMO_REGISTER:
+ /* Okay, I'm registered. (Nothing needs to be done here.) */
+ return;
+
+
+
+ /*!
+ * IGNORE local native method un-registration.
+ */
+ case JVMCFG_JLOBJECT_NMO_UNREGISTER:
+ /* Okay, I'm unregistered.(Nothing needs to be done here.)*/
+ return;
+
+
+ /*!
+ * Somebody goofed. There is an incomplete definition somewhere.
+ */
+ default:
+ /*!
+ * Due to the invocation of @link
+ #native_verify_ordinal_definition()
+ native_verify_ordinal_definition()@endlink above,
+ * this condition @e should not be reached unless one
+ * of the NATIVE_TABLE_JLxxxxx_RETURNTYPE macros does not
+ * have all of the entries that it needs.
+ */
+ exit_throw_exception(EXIT_JVM_INTERNAL,
+ JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
+/*NOTREACHED*/
+ return; /* Satisfy compiler */
+ }
+ return; /* Satisfy compiler */
+
+} /* END of native_run_method() */
+
+
+/* EOF */
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/native.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/native.h?rev=307257&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/native.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/native.h Fri Oct 7 21:27:56 2005
@@ -0,0 +1,64 @@
+#ifndef _native_h_included_
+#define _native_h_included_
+
+/*!
+ * @file native.h
+ *
+ * @brief Local native method interface between JNI and JVM.
+ *
+ * Native methods that are implemented @e within the JVM may circumvent
+ * the full-blown JNI interface by calling these functions.
+ *
+ *
+ * @section Control
+ *
+ * \$URL: https://svn.apache.org/path/name/native.h $ \$Id: native.h 0 09/28/2005 dlydick $
+ *
+ * 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.
+ *
+ * @version \$LastChangedRevision: 0 $
+ *
+ * @date \$LastChangedDate: 09/28/2005 $
+ *
+ * @author \$LastChangedBy: dlydick $
+ * Original code contributed by Daniel Lydick on 09/28/2005.
+ *
+ * @section Reference
+ *
+ */
+
+ARCH_COPYRIGHT_APACHE(native, h, "$URL: https://svn.apache.org/path/name/native.h $ $Id: native.h 0 09/28/2005 dlydick $");
+
+/* Prototypes for functions in 'native.c' */
+
+extern 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);
+
+extern 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);
+
+#endif /* _native_h_included_ */
+
+/* EOF */
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/nts.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/nts.c?rev=307257&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/nts.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/nts.c Fri Oct 7 21:27:56 2005
@@ -0,0 +1,530 @@
+/*!
+ * @file nts.c
+ *
+ * @brief Manipulate null-terminated (@link #rchar rchar@endlink)
+ * character strings.
+ *
+ * There are three character string types in this program:
+ * null-terminated @link #rchar (rchar)@endlink strings
+ * @e ala 'C' language, UTF-8
+ * @link #CONSTANT_Utf8_info (CONSTANT_Utf8_info)@endlink strings,
+ * and Unicode @link #jchar (jchar)[]@endlink strings.
+ *
+ *
+ * @section Control
+ *
+ * \$URL: https://svn.apache.org/path/name/nts.c $ \$Id: nts.c 0 09/28/2005 dlydick $
+ *
+ * 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.
+ *
+ * @version \$LastChangedRevision: 0 $
+ *
+ * @date \$LastChangedDate: 09/28/2005 $
+ *
+ * @author \$LastChangedBy: dlydick $
+ * Original code contributed by Daniel Lydick on 09/28/2005.
+ *
+ * @section Reference
+ *
+ */
+
+#include "arch.h"
+ARCH_COPYRIGHT_APACHE(nts, c, "$URL: https://svn.apache.org/path/name/nts.c $ $Id: nts.c 0 09/28/2005 dlydick $");
+
+
+#include <string.h>
+
+#include "jvmcfg.h"
+#include "cfmacros.h"
+#include "classfile.h"
+#include "nts.h"
+
+
+/*!
+ * @brief Convert null-terminated string buffer into UTF8 buffer.
+ *
+ *
+ * @param inbfr String (rchar *) string
+ *
+ *
+ * @returns UTF8 structure containing length and rchar bfr (plus tag),
+ * but return in (cp_info_dup) for full proper word alignment.
+ * When done with the data, call HEAP_FREE_DATA() on it.
+ *
+ * @c @b rc-\>bytes UTF8 version of @b inbfr string
+ *
+ * @c @b rc-\>length Number of UTF8 bytes in
+ * @c @b rc-\>bytes
+ */
+
+cp_info_dup *nts_prchar2utf(rchar *inbfr)
+{
+ jshort len = strlen(inbfr);
+
+ /*
+ * Allocate enough heap space for output string, but within the
+ * context of the output result type. The size calculation
+ * replaces generic (cp_info) with specifc (CONSTANT_Utf8_info)
+ * info, adjusting for the amount of string data to be stored
+ * into the result.
+ */
+ cp_info_dup *rc = HEAP_GET_DATA(sizeof(cp_info_dup) -
+ sizeof(cp_info) +
+ sizeof(CONSTANT_Utf8_info) -
+ sizeof(u1) +
+ len,
+ rfalse);
+
+ /* Move (rchar *) string into (CONSTANT_Utf8_info) */
+ CONSTANT_Utf8_info *pcpui = PTR_THIS_CP_Utf8(rc);
+ pcpui->tag = CONSTANT_Utf8;
+ pcpui->length = len;
+
+ memcpy((jubyte *) pcpui->bytes, inbfr, len);
+
+ rc->empty[0] = FILL_INFO_DUP0;
+ rc->empty[1] = FILL_INFO_DUP1;
+ rc->empty[2] = FILL_INFO_DUP2;
+
+ return(rc);
+
+} /* END of nts_prchar2utf() */
+
+
+/*!
+ * @brief Convert null-terminated string into Unicode buffer.
+ *
+ *
+ * @param[in] inbfr Null-terminated string
+ *
+ * @param[out] outbfr Buffer for resulting Unicode character string.
+ * This buffer will need to be the same size in
+ * Unicode (jchar) characters as @b inbfr is in
+ * native characters (rchar) since the
+ * conversion is simply putting the ASCII
+ * into the LS byte of the Unicode character.
+ *
+ *
+ * @returns Two returns, one a buffer, the other a count:
+ *
+ * *outbfr Unicode version of @b inbfr string in @b outbfr
+ *
+ * charcnvcount (Return value of function) Number of Unicode
+ * characters in @b outbfr.
+ *
+ */
+
+jshort nts_prchar2unicode(rchar *inbfr, jchar *outbfr)
+{
+ jshort charcnvcount;
+
+ jchar inbfrcnv;
+
+ jshort len = strlen(inbfr);
+
+
+ for (charcnvcount = 0; charcnvcount < len; charcnvcount++)
+ {
+ /* Put ASCII into LS byte of output */
+ inbfrcnv = 0;
+ inbfrcnv |= inbfr[charcnvcount];
+
+ outbfr[charcnvcount] = inbfrcnv;
+
+ }
+
+ /* Done. Return number of characters processed */
+ return(charcnvcount);
+
+} /* END of nts_prchar2unicode() */
+
+
+
+
+/*!
+ * @brief Format a string buffer into UTF8 buffer with Java class
+ * information, including number of array dimensions.
+ *
+ *
+ * @param inbfr String (rchar *) string
+ *
+ * @param arraydims Number of array dimensions
+ *
+ *
+ * @returns UTF8 structure containing length and rchar bfr (plus tag),
+ * but return in (cp_info_dup) for full proper word alignment.
+ * When done with the data, call HEAP_FREE_DATA() on it.
+ * With @b inbfr of @c @b some/path/name/filename,
+ * the result will be, with 3 array dimensions:
+ *
+ * @verbatim
+
+ [[[Lsome/path/name/filename;\0
+
+ @endverbatim
+ *
+ * The string then has a @c @b \\0 NUL character
+ * appended to it for strfn() convenience, but this is
+ * not reported in the UTF8 string length.
+ *
+ *
+ * @c @b rc-\>bytes UTF8 version of @b inbfr string
+ *
+ * @c @b rc-\>length Number of UTF8 bytes in
+ * @c @b rc-\>bytes
+ *
+ */
+
+cp_info_dup *nts_prchar2utf_classname(rchar *inbfr,
+ jvm_array_dim arraydims)
+{
+ jshort inbfrlen = strlen(inbfr);
+
+ /*
+ * Allocate enough heap space for output string, but within the
+ * context of the output result type. The size calculation
+ * replaces generic (cp_info) with specifc (CONSTANT_Utf8_info)
+ * info, adjusting for the amount of string data to be stored
+ * into the result, as adjusted for Java class name formatting.
+ */
+
+ /* This calculation follows the above description of text format */
+ int fmtlen = arraydims + /* Bracket characters */
+ sizeof(u1) + /* Type specifier */
+ inbfrlen + /* Data */
+ sizeof(u1) + /* Type terminator */
+ sizeof(u1); /* NUL character */
+
+ cp_info_dup *rc =
+ HEAP_GET_DATA(sizeof(cp_info_dup) - /* Enclosing structure */
+ sizeof(cp_info) + /* Basic type */
+ sizeof(CONSTANT_Utf8_info) - /* UTF8 type */
+ sizeof(u1) + /* Data place holder */
+ fmtlen, /* UTF8 data area */
+ rfalse);
+
+ /* Move (rchar *) string into (CONSTANT_Utf8_info) */
+ CONSTANT_Utf8_info *pcpui = PTR_THIS_CP_Utf8(rc);
+ pcpui->tag = CONSTANT_Utf8;
+ pcpui->length = fmtlen - sizeof(u1);/*Adjust out trailing \0 rchar*/
+
+ /* Format array dimensions, Java type name, class name, terminator*/
+ jvm_utf_string_index utfidx = 0;
+ for (utfidx = 0; utfidx < arraydims; utfidx++)
+ {
+ pcpui->bytes[utfidx] = BASETYPE_CHAR_ARRAY;
+ }
+
+ pcpui->bytes[utfidx] = BASETYPE_CHAR_L;
+ utfidx++;
+
+ memcpy((jubyte *) &pcpui->bytes[utfidx], inbfr, inbfrlen);
+
+ rc->empty[0] = FILL_INFO_DUP0;
+ rc->empty[1] = FILL_INFO_DUP1;
+ rc->empty[2] = FILL_INFO_DUP2;
+
+ pcpui->bytes[utfidx + inbfrlen] = BASETYPE_CHAR_L_TERM;
+ pcpui->bytes[utfidx + inbfrlen + 1] = '\0';
+
+ return(rc);
+
+} /* END of nts_prchar2utf_classname() */
+
+
+/*!
+ * @brief Report the number of array dimensions prefixing a Java type
+ * string.
+ *
+ * No overflow condition is reported since it is assumed that @b inbfr
+ * is a valid (rchar *) string. Notice that because this logic checks
+ * @e only for array specifiers and does not care about the rest of the
+ * string, it may be used to evaluate field descriptions, which will
+ * not contain any class formatting information.
+ *
+ * If there is even a @e remote possibility that more than
+ * CONSTANT_MAX_ARRAY_DIMS dimensions will be found, compare the
+ * result of this function with the result of nts_prchar_isarray().
+ * If there is a discrepancy, then there was an overflow here.
+ * Properly formatted class files will @e never contain code with
+ * this condition.
+ *
+ * @note This function is identical to nts_get_prchararraydims()
+ * except that it works on (rchar *) instead of
+ * (CONSTANT_Utf8_info *).
+ *
+ *
+ * @param inbfr (rchar *) string.
+ *
+ *
+ * @returns Number of array dimensions in string. For example,
+ * this string contains three array dimensions:
+ *
+ * @verbatim
+
+ [[[Lsome/path/name/filename;
+
+ @endverbatim
+ *
+ * The string does @e not have a @c @b \\0 NUL
+ * character appended in this instance. If more than
+ * CONSTANT_MAX_ARRAY_DIMS are located, the
+ * result is zero-- no other error is reported.
+ *
+ */
+
+jvm_array_dim nts_get_prchar_arraydims(rchar *inbfr)
+{
+ /* Make return code wider than max to check overflow */
+ u4 rc = 0;
+
+ /* Start scanning at beginning of string */
+ u1 *pclsname = (u1 *) inbfr;
+
+ /* Keep scanning until no more array specifications are found */
+ while (BASETYPE_CHAR_ARRAY == *pclsname++)
+ {
+ rc++;
+ }
+
+ /* Check overflow, return default if so, else number of dimensions*/
+ if (CONSTANT_MAX_ARRAY_DIMS < rc)
+ {
+ return(LOCAL_CONSTANT_NO_ARRAY_DIMS);
+ }
+ else
+ {
+ /* Perform narrowing conversion into proper type for max */
+ return((jvm_array_dim) rc);
+ }
+
+} /* END of nts_get_prchar_arraydims() */
+
+
+/*!
+ * @brief Test whether or not a Java type string is an array or not.
+ *
+ *
+ * @param inbfr (rchar *) string.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if this is an array
+ * specfication, else @link #rfalse rfalse@endlink.
+ *
+ */
+
+rboolean nts_prchar_isarray(rchar *inbfr)
+{
+ return((BASETYPE_CHAR_ARRAY == (u1) inbfr[0]) ? rtrue : rfalse);
+
+} /* END of nts_prchar_isarray() */
+
+
+/*!
+ * @brief Verify if a null-terminated string contains PRIMATIVE
+ * formatting or not. May be prefixed with array specifiers.
+ * Everything after the base type character is ignored.
+ *
+ *
+ * @param src Pointer to null-terminated string.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if string is formtted as
+ * @c @b LClassName; but
+ * @link #rfalse rfalse@endlink otherwise, may also have
+ * array descriptor prefixed,
+ * thus @c @b [[LClassName;
+ *
+ * @link #rtrue rtrue@endlink if string is formatted as
+ * @c @b \@ (where @c @b \@ is any
+ * @link #BASETYPE_CHAR_B BASETYPE_CHAR_x@endlink character),
+ * @link #rfalse rfalse@endlink otherwise. May also have
+ * array descriptor prefixed,
+ * thus @c @b [[\@, eg, @c @b [[I or @c @b [[[[D
+ *
+ */
+
+rboolean nts_prchar_isprimativeformatted(rchar *src)
+{
+ jvm_array_dim arraydims = nts_get_prchar_arraydims(src);
+
+ /*
+ * Chk if @e any primative base type,
+ * but NOT class (the @c @b L fmt)
+ */
+ switch (src[arraydims])
+ {
+ case BASETYPE_CHAR_B:
+ case BASETYPE_CHAR_C:
+ case BASETYPE_CHAR_D:
+ case BASETYPE_CHAR_F:
+ case BASETYPE_CHAR_I:
+ case BASETYPE_CHAR_J:
+ case BASETYPE_CHAR_S:
+ case BASETYPE_CHAR_Z:
+ return(rtrue);
+
+ default:
+ return(rfalse);
+ }
+
+} /* END of nts_prchar_isprimativeformatted() */
+
+
+/*!
+ * @brief Verify if a null-terminated string contains CLASS formatting
+ * or not.
+ *
+ *
+ * @param src Pointer to null-terminated string.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if string is formatted as
+ * @c @b LClasSName; but
+ * @link #rfalse rfalse@endlink otherwise. May also have
+ * array descriptor prefixed, thus @c @b [[LClassName;
+ *
+ *
+ * @note This function works just like utf_isclassformatted() except
+ * that it works on (rchar *) strings rather than
+ * on (CONSTANT_Utf8_info) strings.
+ */
+
+rboolean nts_prchar_isclassformatted(rchar *src)
+{
+ u2 idx;
+ rint rc = rfalse;
+
+ /* Chk array or class specifier. If neither, cannot be formatted */
+ switch (src[0])
+ {
+ case BASETYPE_CHAR_ARRAY:
+ case BASETYPE_CHAR_L:
+ break;
+ default:
+ return(rfalse);
+ }
+
+ /*
+ * Now assume a potentially formatted string.
+ * Check for termination byte next. If not present,
+ * nothing else matters and string cannot be formatted.
+ */
+ u1 *pbytes = src;
+ int len = strlen(src);
+
+ for (idx = 0; idx < len; idx++)
+ {
+ if (BASETYPE_CHAR_L_TERM == pbytes[idx])
+ {
+ rc = rtrue;
+ break;
+ }
+ }
+
+ /* If not terminated, then cannot be class formatted */
+ if (rfalse == rc)
+ {
+ return(rc);
+ }
+
+ /* Check initial formatting, including array spec */
+ jvm_array_dim arraydims = nts_get_prchar_arraydims(src);
+
+ /* If any array specs, look immediately past them for class spec */
+ if (BASETYPE_CHAR_L == pbytes[arraydims])
+ {
+ return(rtrue);
+ }
+ else
+ {
+ return(rfalse);
+ }
+
+} /* END of nts_prchar_isclassformatted() */
+
+
+/*!
+ * @brief Strip a null-terminated string of any class formatting it
+ * contains and return result in a heap-allocated buffer. When done
+ * with this result, perform HEAP_DATA_FREE(result) to return buffer
+ * to heap.
+ *
+ *
+ * @param inbfr Pointer to null-terminated string that is potentially
+ * formatted as @c @b LClassName; and which may
+ * also have array descriptor prefixed, thus
+ * @c @b [[LClassName;
+ *
+ *
+ * @returns heap-allocated buffer containing @c @b ClassName
+ * with no formatting, regardless of input formatting or lack
+ * thereof.
+ *
+ *
+ * @note This function works just like
+ * utf_utf2utf_unformatted_classname()
+ * except that it takes a (rchar *) string
+ * rather than a (CONSTANT_Utf8_info) string
+ * and returns a (rchar *).
+ *
+ */
+
+rchar *nts_prchar2prchar_unformatted_classname(rchar *inbfr)
+{
+ int inbfrlen = strlen(inbfr);
+ rint isfmt = nts_prchar_isclassformatted(inbfr);
+ jvm_array_dim arraydims = nts_get_prchar_arraydims(inbfr);
+ rchar *psemi;
+ int allocsize;
+ int startposn;
+
+ if (rtrue == isfmt)
+ {
+ psemi = strchr(inbfr, BASETYPE_CHAR_L_TERM);
+ psemi--;
+
+ allocsize = inbfrlen - /* Input data size */
+ arraydims - /* Array specifiers */
+ sizeof(u1) - /* Type specifier */
+ sizeof(u1) + /* Type terminator */
+ sizeof(u1); /* NUL terminator */
+
+ startposn = arraydims + sizeof(u1); /* Skip array & type */
+ }
+ else
+ {
+ psemi = (rchar *) rnull;
+ allocsize = inbfrlen + /* Input data size */
+ sizeof(u1); /* NUL terminator */
+
+ startposn = 0; /* Copy the whole string */
+ }
+
+ rchar *rc = HEAP_GET_DATA(allocsize, rfalse);
+
+ /* Extract input class name from input buffer, add null char */
+ memcpy(rc, &inbfr[startposn], allocsize);
+ rc[allocsize - sizeof(u1)] = '\0';
+
+ return(rc);
+
+} /* END of nts_prchar2prchar_unformatted_classname() */
+
+
+/* EOF */
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/nts.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/nts.h?rev=307257&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/nts.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/nts.h Fri Oct 7 21:27:56 2005
@@ -0,0 +1,73 @@
+#ifndef _nts_h_defined_
+#define _nts_h_defined_
+
+/*!
+ * @file nts.h
+ *
+ * @brief Manipulate null-terminated (@link #rchar rchar@endlink)
+ * character strings.
+ *
+ * There are three character string types in this program:
+ * null-terminated @link #rchar (rchar)@endlink strings
+ * @e ala 'C' language, UTF-8
+ * @link #CONSTANT_Utf8_info (CONSTANT_Utf8_info)@endlink strings,
+ * and Unicode @link #jchar (jchar)[]@endlink strings.
+ *
+ *
+ * @section Control
+ *
+ * \$URL: https://svn.apache.org/path/name/nts.h $ \$Id: nts.h 0 09/28/2005 dlydick $
+ *
+ * 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.
+ *
+ * @version \$LastChangedRevision: 0 $
+ *
+ * @date \$LastChangedDate: 09/28/2005 $
+ *
+ * @author \$LastChangedBy: dlydick $
+ * Original code contributed by Daniel Lydick on 09/28/2005.
+ *
+ * @section Reference
+ *
+ */
+
+ARCH_COPYRIGHT_APACHE(nts, h, "$URL: https://svn.apache.org/path/name/nts.h $ $Id: nts.h 0 09/28/2005 dlydick $");
+
+/* Prototypes for functions in 'nts.c' */
+
+extern cp_info_dup *nts_prchar2utf(rchar *inbfr);
+
+extern jshort nts_prchar2unicode(rchar *inbfr, jchar *outbfr);
+
+extern cp_info_dup *nts_prchar2utf_classname(rchar *inbfr,
+ jvm_array_dim arraydims);
+
+extern jvm_array_dim nts_get_prchar_arraydims(rchar *inbfr);
+
+extern rboolean nts_prchar_isarray(rchar *inbfr);
+
+extern rboolean nts_prchar_isprimativeformatted(rchar *src);
+
+extern rboolean nts_prchar_isclassformatted(rchar *src);
+
+extern rchar *nts_prchar2prchar_unformatted_classname(rchar *inbfr);
+
+#endif /* _nts_h_defined_ */
+
+
+/* EOF */