harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ge...@apache.org
Subject 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...
Date Sat, 08 Oct 2005 04:29:29 GMT
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 */



Mime
View raw message