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 [20/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/opcode.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/opcode.c?rev=307257&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/opcode.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/opcode.c Fri Oct  7 21:27:56 2005
@@ -0,0 +1,3385 @@
+/*!
+ * @file opcode.c
+ *
+ * @brief Java Virtual Machine inner loop virtual instruction execution.
+ *
+ * A specific group of exceptions that may be thrown by JVM execution
+ * (spec section 2.16.4 unless specified otherwise) are not typically
+ * checked by the Java program and stop thread execution unless caught
+ * by a Java @c @b catch block.
+ *
+ * <ul>
+ * <li>
+ * @b ArithmeticException    Integer divide by zero
+ * </li><li>
+ * @b ArrayStoreException    Storage compatibility error between
+ *                           array type lvalue vs component rvalue
+ * </li><li>
+ * @b ClassCastException     Type narrowing loses significance or
+ *                           casting of an object to a type that
+ *                           is not valid.
+ * </li><li>
+ * @b IllegalMonitorStateException  Thread attempted to wait() or
+ *                           notify()  on an object that it has
+ *                           not locked.
+ * </li><li>
+ * @b IndexOutOfBoundsException An index or a subrange was outside the
+ *                           limits \>=0 unto \< lenghth/size for
+ *                           an array, string, or vector.
+ * </li><li>
+ * @b NegativeArraySizeException Attempted to create an array with a
+ *                           negative number of elements.
+ * 
+ * </li><li>
+ * @b NullPointerException   An object reference to a
+ *                           @link #jvm_object_hash_null
+                             jvm_object_hash_null@endlink object
+ *                           was attempted instead of to a real
+ *                           and valid object.
+ *
+ * </li><li>
+ * @b SecurityException      Violation of security policy.
+ * </li>
+ * </ul>
+ *
+ *
+ *
+ * A suite of errors may also be thrown that Java programs normally
+ * to not attempt to @c @b catch and which terminate JVM
+ * execution:
+ *
+ * <ul>
+ * <li>
+ * @link #JVMCLASS_JAVA_LANG_LINKAGEERROR LinkageError@endlink Loading,
+ *                    linking, or initialization error
+ *                    (2.17.2, 2.17.3, 2.17.4).  May also be
+ *                    thrown at run time.
+ * </li>
+ *
+ * <li>
+ * Loading Errors (2.17.2):
+ * <ul>
+ *     <li>
+ *     @b ClassFormatError        Binary data is not a valid class file.
+ *     </li><li>
+ *     @b ClassCircularityError   Class hierarchy eventually references
+ *                                itself.
+ *     </li><li>
+ *     @b NoClassDefFoundError    Class cannot be found by loader.
+ *     </li><li>
+ *     @b UnsupportedClassVersionError JVM does not support this version
+ *                                of the class file specification.
+ *     </li>
+ * </ul>
+ * </li>
+ *
+ * <li>
+ * Linking Errors (2.17.3) (subclass of @link
+   #JVMCLASS_JAVA_LANG_INCOMPATIBLECLASSCHANGEERROR 
+   IncompatibleClassChangeError@endlink):
+ * <ul>
+ *     <li>
+ *     @b NosuchFieldError      Attempt to reference non-existent field
+ *     </li><li>
+ *     @b NoSuchMethodError     Attempt to reference non-existent method
+ *     </li><li>
+ *     @b InstantiationError    Attempt to instantiate abstract class
+ *     </li><li>
+ *     @b IllegalAccessError    Attempt to reference a field or method
+ *                              that is not in scope (typically not
+ *                              not @c @b public ).
+ *     </li>
+ * </ul>
+ * </li>
+ *
+ * <li>
+ * Verification Errors (2.17.3):
+ * <ul>
+ *     <li>
+ *     @b VerifyError    Class fails integrity checks of the verifier.
+ *     </li>
+ * </ul>
+ * </li>
+ *
+ * <li>
+ * Initialization Errors (2.17.4):
+ * <ul>
+ *     <li>
+ *     @b ExceptionInInitializerError   A static initializer of a static
+ *                                   field initializer threw something
+ *                                   that was neither a
+ *                                   @c @b java.lang.Error
+ *                                   or its subclass.
+ *     </li>
+ * </ul>
+ * </li>
+ *
+ * <li>
+ * Run-time instances of @link #JVMCLASS_JAVA_LANG_LINKAGEERROR
+   LinkageError@endlink:
+ * <ul>
+ *     <li>
+ *     @b AbstractMethodError    Invocation of an abstract method.
+ *     </li><li>
+ *     @b UnsatisfiedLinkError   Cannot load native method (shared obj).
+ *     </li>
+ * </ul>
+ * </li>
+ *
+ * <li>
+ * Resource limitations, via subclass of @link
+   #JVMCLASS_JAVA_LANG_VIRTUALMACHINEERROR VirtualMachineError@endlink:
+ * <ul>
+ *     <li>
+ *     @b InternalError         JVM software or host software/hardware
+ *                              (may occur asynchronously, any time)
+ *     </li><li>
+ *     @b OutOfMemoryError      JVM cannot get enough memory for
+ *                              request, even after GC/mmgmt.
+ *     </li><li>
+ *     @b StackOverflowError    Out of JVM stack space, typically due
+ *                              to infinite recursion on a method.
+ *     </li><li>
+ *     @b UnknownError          JVM cannot determine the actual cause.
+ *     </li>
+ * </ul>
+ * </li>
+ * </ul>
+ *
+ *
+ * @todo The code fragment macros used by the opcode switch in
+ * @link #opcode_run() opcode_run()@endlink need to have the
+ * local variables documented as to which as required upon
+ * macro startup and which are set for use at macro completion.
+ *
+ *
+ * @section Control
+ *
+ * \$URL: https://svn.apache.org/path/name/opcode.c $ \$Id: opcode.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(opcode, c, "$URL: https://svn.apache.org/path/name/opcode.c $ $Id: opcode.c 0 09/28/2005 dlydick $");
+
+#include "jvmcfg.h"
+#include "cfmacros.h"
+#include "classfile.h"
+#include "exit.h"
+#include "gc.h" 
+#include "jvm.h"
+#include "jvmclass.h"
+#include "linkage.h"
+#include "method.h"
+#include "native.h"
+#include "opcode.h"
+#include "utf.h"
+#include "util.h"
+
+/*!
+ * @name Macro support for inner loop opcodes.
+ *
+ * @brief Common operations that are used in numerous opcodes
+ * are gathered here so as to improve accuracy of implementation
+ * and simplify the code.
+ *
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+/*!
+ * @brief Retrieve a two-byte operand that the PC points to.
+ *
+ *
+ * Store thw two-byte operand into the requested @link #u2 u2@endlink
+ * variable, then increment the program counter to the next byte code
+ * following it.
+ *
+ * @param u2var  Name of a @link #u2 u2@endlink variable that will
+ *               receive the two bytes of operand from with the
+ *               instruction.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ */
+#define GET_U2_OPERAND(u2var)                  \
+    u2var = GETRS2((u2 *) &pcode[pc->offset]); \
+    pc->offset += sizeof(u2)
+ 
+
+/*!
+ * @name Validate a constant_pool entry
+ *
+ */
+
+
+/*@{ */ /* Begin grouped definitions */
+
+/*!
+ * @brief Check that a constant_pool entry contains
+ * a specific of tag for this operation.
+ *
+ *
+ * @param u2var  Name of a @link #u2 u2@endlink variable that
+ *               contains a constant_pool entry to be examined.
+ *
+ * @param cptag1 First constant_pool tag that is valid for this
+ *               operation.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_VERIFYERROR
+ *         @link #JVMCLASS_JAVA_LANG_VERIFYERROR
+         if the constant_pool entry does not have the right tag@endlink.
+ *
+ */
+#define CHECK_CP_TAG(u2var, cptag1)                             \
+    if (cptag1 != CP_TAG(pcfs, u2var))                          \
+    {                                                           \
+        /* Somebody is confused */                              \
+        thread_throw_exception(thridx,                          \
+                               THREAD_STATUS_THREW_ERROR,       \
+                               JVMCLASS_JAVA_LANG_VERIFYERROR); \
+/*NOTREACHED*/                                                  \
+    }
+
+
+/*!
+ * @brief Check that a constant_pool entry contains
+ * the right kind of tag for this operation, from a choice of two.
+ *
+ *
+ * @param u2var  Name of a @link #u2 u2@endlink variable that
+ *               contains a constant_pool entry to be examined.
+ *
+ * @param cptag1 First constant_pool tag that is valid for this
+ *               operation.
+ *
+ * @param cptag2 Second constant_pool tag that is valid for this
+ *               operation.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_VERIFYERROR
+ *         @link #JVMCLASS_JAVA_LANG_VERIFYERROR
+         if the constant_pool entry does not have the right tag@endlink.
+ *
+ */
+#define CHECK_CP_TAG2(u2var, cptag1, cptag2)                    \
+    if ((cptag1 != CP_TAG(pcfs, u2var)) &&                      \
+        (cptag2 != CP_TAG(pcfs, u2var)))                        \
+    {                                                           \
+        /* Somebody is confused */                              \
+        thread_throw_exception(thridx,                          \
+                               THREAD_STATUS_THREW_ERROR,       \
+                               JVMCLASS_JAVA_LANG_VERIFYERROR); \
+/*NOTREACHED*/                                                  \
+    }
+
+
+/*!
+ * @brief Check that a constant_pool entry contains
+ * the right kind of tag for this operation, from a choice of three.
+ *
+ *
+ * @param u2var  Name of a @link #u2 u2@endlink variable that
+ *               contains a constant_pool entry to be examined.
+ *
+ * @param cptag1 First constant_pool tag that is valid for this
+ *               operation.
+ *
+ * @param cptag2 Second constant_pool tag that is valid for this
+ *               operation.
+ *
+ * @param cptag3 Third constant_pool tag that is valid for this
+ *               operation.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_VERIFYERROR
+ *         @link #JVMCLASS_JAVA_LANG_VERIFYERROR
+         if the constant_pool entry does not have the right tag@endlink.
+ *
+ */
+#define CHECK_CP_TAG3(u2var, cptag1, cptag2, cptag3)            \
+    if ((cptag1 != CP_TAG(pcfs, u2var)) &&                      \
+        (cptag2 != CP_TAG(pcfs, u2var)) &&                      \
+        (cptag3 != CP_TAG(pcfs, u2var)))                        \
+    {                                                           \
+        /* Somebody is confused */                              \
+        thread_throw_exception(thridx,                          \
+                               THREAD_STATUS_THREW_ERROR,       \
+                               JVMCLASS_JAVA_LANG_VERIFYERROR); \
+/*NOTREACHED*/                                                  \
+    }
+
+/*@} */ /* End of grouped definitions */
+
+/*!
+ * @brief Force conversion of any Java type variable
+ * of @c @b sizeof(jint) into a @link #jint jint@endlink
+ * variable, but without conversion of contents.
+ *
+ *
+ * This macro is typically used to move a
+ * @link #jvm_object_hash jobject@endlink reference or a
+ * @link #jfloat jfloat@endlink into a @link #jint jint@endlink
+ * word, but suppress type conversion between the
+ * source and destination variables.  It derives the
+ * address of the 32-bit source value, casts it as a
+ * pointer to the destination data type, then extracts
+ * that type.
+ *
+ * @warning This macro @e must have a 32-bit word as its source.
+ *          For use with smaller types, perform a widening conversion
+ *          first (such as @link #jboolean jboolean@endlink) to
+ *          @link #jint jint@endlink.  Then and only then will
+ *          the target type work correctly.
+ *
+ * @warning Since this macro takes the address of its source parameter,
+ * it will only work for variables, not for expressions!
+ *
+ *
+ * @param var_sizeofjint  Any 32-bit variable.  If it is a smaller
+ *                        type, such as (jboolean), perform a
+ *                        widening conversion into (jint) first.
+ *
+ * @returns (jint) version of @b var_sizeofjint without conversion
+ *          of contents (such as jfloat-to-jint might want to do).
+ *
+ *
+ * @todo A careful review of this macro across different compilers
+ *       is very much in order.
+ *
+ */
+#define FORCE_JINT(var_sizeofjint) \
+    (*((jint *) ((jvoid *) &var_sizeofjint)))
+
+
+/*!
+ * @brief Force conversion of any Java type variable
+ * of @c @b sizeof(jint) into a @link #jfloat jfloat@endlink
+ * variable, but without conversion of contents.
+ *
+ *
+ * This macro is typically used to move a
+ * @link #jint jint@endlink into a @link #jint jint@endlink
+ * word, but suppress type conversion between the
+ * source and destination variables.
+ *
+ * @warning For comments on the dangers of using this macro,
+ *          please refer to @link #FORCE_JINT() FORCE_JINT()@endlink.
+ *
+ *
+ * @param var_sizeofjint  Any 32-bit variable.
+ *
+ * @returns (jfloat) version of @b var_sizeofjint without conversion
+ *          of contents (such as jint-to-jfloat might want to do).
+ *
+ *
+ * @todo A careful review of this macro across different compilers
+ *       is very much in order.
+ *
+ */
+#define FORCE_JFLOAT(var_sizeofjint) \
+    (*((jfloat *) ((jvoid *) &var_sizeofjint)))
+
+
+/*!
+ * @brief Calculate method_info pointer from program counter
+ *
+ * During the calculation, various scratch variables are
+ * loaded and used to simplify the code.  The final result
+ * is a (method_info *) stored the local variable @b pmth
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink.
+ *
+ */
+#define CALCULATE_METHOD_INFO_FROM_PC                    \
+    clsidxmisc = GET_PC_FIELD_IMMEDIATE(thridx, clsidx); \
+    mthidxmisc = GET_PC_FIELD_IMMEDIATE(thridx, mthidx); \
+    pcfsmisc   = CLASS_OBJECT_LINKAGE(clsidxmisc)->pcfs; \
+    pmth       = METHOD(clsidxmisc, mthidxmisc)
+
+
+/*!
+ * @brief Calculate ClassFile pointer from a class reference.
+ *
+ * During the calculation, various scratch variables are
+ * loaded and used to simplify the code.  Two final results
+ * include a (CONSTANT_Class_info *) stored in the local variable
+ * @b pcpd_Class stored the local variable @b pcfsmisc
+ * and a (CONSTANT_Class_info *) stored in the local variable
+ * @b pcpd_Class
+ *
+ * @param clsnameidx  constant_pool index into class file of current
+ *                    class (as indicated in the program counter)
+ *                    that is a class reference entry.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink.
+ *
+ *
+ */
+#define CALCULATE_CLASS_INFO_FROM_CLASS_REFERENCE(clsnameidx)          \
+    pcpd       = pcfs->constant_pool[clsnameidx];                      \
+    pcpd_Class = PTR_THIS_CP_Class(pcpd);                              \
+    clsidxmisc = pcpd_Class->LOCAL_Class_binding.clsidxJVM;            \
+    if (jvm_class_index_null == clsidxmisc)                            \
+    {                                                                  \
+        /* Need local variable to avoid possible expansion confusion */\
+        jvm_constant_pool_index cpidxOLD = clsnameidx;                 \
+                                                                       \
+        /* If class is not loaded, go retrieve it by UTF8 class name */\
+        LATE_CLASS_LOAD(cpidxOLD);                                     \
+    }                                                                  \
+    pcfsmisc = CLASS_OBJECT_LINKAGE(clsidxmisc)->pcfs; /* Extra ; */
+
+
+/*!
+ * @brief Attempt to load a class that is not currently loaded.
+ *
+ *
+ * @param clsnameidx  CONSTANT_Utf8_info constant_pool index
+ *                    to class name
+ *
+ * @return @link #rvoid rvoid@endlink
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_NOCLASSDEFFOUNDERROR
+ *         @link #JVMCLASS_JAVA_LANG_NOCLASSDEFFOUNDERROR
+           if requested class cannot be located@endlink.
+ *
+ */
+#define LATE_CLASS_LOAD(clsnameidx)                                  \
+                                                                     \
+    pcpd       = pcfs->constant_pool[clsnameidx]; /* Class name */   \
+    pcpd_Class = PTR_THIS_CP_Class(pcpd);                            \
+                                                  /* UTF8 string */  \
+    pcpd       = pcfs->constant_pool[pcpd_Class->name_index];        \
+    pcpd_Utf8  = PTR_THIS_CP_Utf8(pcpd);                             \
+                                                                     \
+    prchar_clsname = utf_utf2prchar(pcpd_Utf8);                      \
+                                                                     \
+    /* Try again to load class */                                    \
+    clsidxmisc = class_load_resolve_clinit(prchar_clsname,           \
+                                           CURRENT_THREAD,           \
+                                           rfalse,                   \
+                                           rfalse);                  \
+                                                                     \
+    HEAP_FREE_DATA(prchar_clsname);                                  \
+                                                                     \
+    /* If class is irretrievable, abort */                           \
+    if (jvm_class_index_null == clsidxmisc)                          \
+    {                                                                \
+        thread_throw_exception(thridx,                               \
+                               THREAD_STATUS_THREW_ERROR,            \
+                           JVMCLASS_JAVA_LANG_NOCLASSDEFFOUNDERROR); \
+/*NOTREACHED*/                                                       \
+    }
+
+
+
+
+/*!
+ * @brief Calculate method_info pointer from a method reference.
+ *
+ * During the calculation, various scratch variables are
+ * loaded and used to simplify the code.  Two final results
+ * include a (method_info *) stored the local variable @b pmth
+ * and a (CONSTANT_Methodref_info *) stored in the local variable
+ * @b pcpd_Methodref
+ *
+ * @param Methodref  constant_pool index into class file of current
+ *                   class (as indicated in the program counter) that
+ *                   is a method reference entry.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR
+ *         @link #JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR
+           if requested method is not found in the class@endlink.
+ *
+ *
+ */
+#define CALCULATE_METHOD_INFO_FROM_METHOD_REFERENCE(Methodref)         \
+    pcpd           = pcfs->constant_pool[Methodref];                   \
+    pcpd_Methodref = PTR_THIS_CP_Methodref(pcpd);                      \
+    clsidxmisc     = pcpd_Methodref->LOCAL_Methodref_binding.clsidxJVM;\
+    if (jvm_class_index_null == clsidxmisc)                            \
+    {                                                                  \
+        /* If class is not loaded, go retrieve it by UTF8 class name */\
+       LATE_CLASS_LOAD(pcpd_Methodref->class_index);                   \
+                                                                       \
+        /* Check if method exists in loaded class */                   \
+        clsidxmisc = pcpd_Methodref->LOCAL_Methodref_binding.clsidxJVM;\
+        if (jvm_class_index_null == clsidxmisc)                        \
+        {                                                              \
+            thread_throw_exception(thridx,                             \
+                                   THREAD_STATUS_THREW_ERROR,          \
+                                JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR); \
+/*NOTREACHED*/                                                         \
+        }                                                              \
+    }                                                                  \
+                                                                       \
+    mthidxmisc = pcpd_Methodref->LOCAL_Methodref_binding.mthidxJVM;    \
+    if (jvm_method_index_bad == mthidxmisc)                            \
+    {                                                                  \
+        thread_throw_exception(thridx,                                 \
+                               THREAD_STATUS_THREW_ERROR,              \
+                                JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR); \
+/*NOTREACHED*/                                                         \
+    }                                                                  \
+                                                                       \
+    pcfsmisc       = CLASS_OBJECT_LINKAGE(clsidxmisc)->pcfs;           \
+    pmth           = pcfsmisc->methods[mthidxmisc]
+
+
+/*!
+ * @brief Check for code attribute index in local method binding.
+ *
+ *
+ * @param codeatridx  Code attribute index from a local method binding
+ *
+ *
+ * @return @link #rvoid rvoid@endlink
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR
+ *         @link #JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR
+      if requested class static field is not found in the class@endlink.
+ *
+ */
+#define CHECK_VALID_CODEATRIDX(codeatridx)                            \
+    if (jvm_attribute_index_bad == codeatridx)                        \
+    {                                                                 \
+        thread_throw_exception(thridx,                                \
+                               THREAD_STATUS_THREW_ERROR,             \
+                               JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR); \
+/*NOTREACHED*/                                                        \
+    }
+
+
+/*!
+ * @brief Check if this method is a static method.
+ *
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ * @return @link #rvoid rvoid@endlink
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_VERIFYERROR
+ *         @link #JVMCLASS_JAVA_LANG_VERIFYERROR
+           if requested method is an object instance method@endlink.
+ *
+ */
+#define CHECK_STATIC_METHOD                                      \
+                                                                 \
+    /* Must be a static method */                                \
+    if (!(ACC_STATIC & pmth->access_flags))                      \
+    {                                                            \
+        thread_throw_exception(thridx,                           \
+                               THREAD_STATUS_THREW_ERROR,        \
+                               JVMCLASS_JAVA_LANG_VERIFYERROR);  \
+/*NOTREACHED*/                                                   \
+    }
+
+
+/*!
+ * @brief Check if this method is an object instance method.
+ *
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ * @return @link #rvoid rvoid@endlink
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_VERIFYERROR
+ *         @link #JVMCLASS_JAVA_LANG_VERIFYERROR
+           if requested method is a static method@endlink.
+ *
+ */
+#define CHECK_INSTANCE_METHOD                                    \
+                                                                 \
+    /* Must be an instance method */                             \
+    if (ACC_STATIC & pmth->access_flags)                         \
+    {                                                            \
+        thread_throw_exception(thridx,                           \
+                               THREAD_STATUS_THREW_ERROR,        \
+                               JVMCLASS_JAVA_LANG_VERIFYERROR);  \
+/*NOTREACHED*/                                                   \
+    }
+
+
+#if 0
+/*!
+ * @brief Check if this method is an @c @b abstract method,
+ * that is, not having a concrete implementation.
+ *
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ * @return @link #rvoid rvoid@endlink
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
+ *         @link #JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
+ if requested method is a method with a concrete implementatino@endlink.
+ *
+ */
+#define CHECK_ABSTRACT_METHOD                                          \
+                                                                       \
+    /* Must not be a concrete method */                                \
+    if (!(ACC_ABSTRACT & pmth->access_flags))                          \
+    {                                                                  \
+        thread_throw_exception(thridx,                                 \
+                               THREAD_STATUS_THREW_ERROR,              \
+\
+/* What exception gets thrown here? Need "not" of InstantiationError */\
+\
+                               JVMCLASS_JAVA_LANG_INSTANTIATIONERROR); \
+/*NOTREACHED*/                                                         \
+    }
+#endif
+
+
+/*!
+ * @brief Check if this method is a concrete method, that is,
+ * not @c @b abstract .
+ *
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ * @return @link #rvoid rvoid@endlink
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
+ *         @link #JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
+           if requested method is an abstract method@endlink.
+ *
+ */
+#define CHECK_NOT_ABSTRACT_METHOD                                      \
+                                                                       \
+    /* Must not be an abstract method */                               \
+    if (ACC_ABSTRACT & pmth->access_flags)                             \
+    {                                                                  \
+        thread_throw_exception(thridx,                                 \
+                               THREAD_STATUS_THREW_ERROR,              \
+                               JVMCLASS_JAVA_LANG_INSTANTIATIONERROR); \
+/*NOTREACHED*/                                                         \
+    }
+
+
+/*!
+ * @brief Check if this object is from a concrete class, that is,
+ * not from an @c @b abstract class.
+ *
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ * @return @link #rvoid rvoid@endlink
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
+ *         @link #JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
+           if requested object is an abstract object@endlink.
+ *
+ */
+#define CHECK_NOT_ABSTRACT_CLASS                                       \
+                                                                       \
+    /* Must not be from an abstract class */                           \
+    if (ACC_ABSTRACT &                                                 \
+        OBJECT_CLASS_LINKAGE(objhashmisc)->pcfs->access_flags)         \
+    {                                                                  \
+        thread_throw_exception(thridx,                                 \
+                               THREAD_STATUS_THREW_ERROR,              \
+                               JVMCLASS_JAVA_LANG_INSTANTIATIONERROR); \
+/*NOTREACHED*/                                                         \
+    }
+
+
+/*!
+ * @brief Check if this object is a scalar, that is, not an array.
+ *
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ * @return @link #rvoid rvoid@endlink
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
+ *         @link #JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
+           if requested method is an array object@endlink.
+ *
+ */
+#define CHECK_NOT_ARRAY_OBJECT                                         \
+                                                                       \
+    /* Must not be an array object */                                  \
+    if (OBJECT_STATUS_ARRAY &                                          \
+        CLASS(OBJECT_CLASS_LINKAGE(objhashmisc)->clsidx).status)       \
+    {                                                                  \
+        thread_throw_exception(thridx,                                 \
+                               THREAD_STATUS_THREW_ERROR,              \
+                               JVMCLASS_JAVA_LANG_INSTANTIATIONERROR); \
+/*NOTREACHED*/                                                         \
+    }
+
+
+/*!
+ * @brief Check if this object is from a normal class, that is,
+ * not from an interface class.
+ *
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ * @return @link #rvoid rvoid@endlink
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
+ *         @link #JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
+           if requested object is from an interface class@endlink.
+ *
+ */
+#define CHECK_NOT_INTERFACE_CLASS                                      \
+                                                                       \
+    /* Must not be from an interface class */                          \
+    if (ACC_INTERFACE &                                                \
+        OBJECT_CLASS_LINKAGE(objhashmisc)->pcfs->access_flags)         \
+    {                                                                  \
+        thread_throw_exception(thridx,                                 \
+                               THREAD_STATUS_THREW_ERROR,              \
+                               JVMCLASS_JAVA_LANG_INSTANTIATIONERROR); \
+/*NOTREACHED*/                                                         \
+    }
+
+
+/*!
+ * @brief Calculate field_info pointer from a field reference.
+ *
+ * During the calculation, various scratch variables are
+ * loaded and used to simplify the code.  Two final results
+ * include a (field_info *) stored the local variable @b pfld
+ * and a (CONSTANT_Fieldref_info *) stored in the local variable
+ * @b pcpd_Fieldref
+ *
+ * @param Fieldref  constant_pool index into class file of current
+ *                  class (as indicated in the program counter) that
+ *                  is a method reference entry.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR
+ *         @link #JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR
+           if requested field is not found in the class@endlink.
+ *
+ */
+#define CALCULATE_FIELD_INFO_FROM_FIELD_REFERENCE(Fieldref)            \
+    pcpd           = pcfs->constant_pool[Fieldref];                    \
+    pcpd_Fieldref = PTR_THIS_CP_Fieldref(pcpd);                        \
+    clsidxmisc     = pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM;  \
+    if (jvm_class_index_null == clsidxmisc)                            \
+    {                                                                  \
+        /* If class is not loaded, go retrieve it by UTF8 class name */\
+        LATE_CLASS_LOAD(pcpd_Fieldref->class_index);                   \
+                                                                       \
+        /* Check if field exists in loaded class */                    \
+        clsidxmisc = pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM;  \
+        if (jvm_class_index_null == clsidxmisc)                        \
+        {                                                              \
+            thread_throw_exception(thridx,                             \
+                                   THREAD_STATUS_THREW_ERROR,          \
+                                JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR);  \
+/*NOTREACHED*/                                                         \
+        }                                                              \
+    }                                                                  \
+                                                                       \
+    fluidxmisc     = pcpd_Fieldref->LOCAL_Fieldref_binding.fluidxJVM;  \
+    if (jvm_field_index_bad == fluidxmisc)                             \
+    {                                                                  \
+        thread_throw_exception(thridx,                                 \
+                               THREAD_STATUS_THREW_ERROR,              \
+                                JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR);  \
+/*NOTREACHED*/                                                         \
+    }                                                                  \
+                                                                       \
+    pcfsmisc       = CLASS_OBJECT_LINKAGE(clsidxmisc)->pcfs;           \
+    fluidxmisc     = pcpd_Fieldref->LOCAL_Fieldref_binding.fluidxJVM;  \
+    pfld           = pcfsmisc                                          \
+                       ->fields[CLASS(clsidxmisc)                      \
+                                 .class_static_field_lookup[fluidxmisc]]
+
+
+/*!
+ * @brief Check for field lookup index in local field binding.
+ *
+ *
+ * @param fluidx  Field lookup index from a local field binding
+ *
+ *
+ * @return @link #rvoid rvoid@endlink
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR
+ *         @link #JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR
+      if requested class static field is not found in the class@endlink.
+ *
+ */
+#define CHECK_VALID_FIELDLOOKUPIDX(fluidx)                           \
+    if (jvm_field_lookup_index_bad == fluidx)                        \
+    {                                                                \
+        thread_throw_exception(thridx,                               \
+                               THREAD_STATUS_THREW_ERROR,            \
+                               JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR); \
+/*NOTREACHED*/                                                       \
+    }
+
+
+/*!
+ * @brief Check if this field is a static field.
+ *
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ * @return @link #rvoid rvoid@endlink
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INCOMPATIBLECLASSCHANGEERROR
+ *         @link #JVMCLASS_JAVA_LANG_INCOMPATIBLECLASSCHANGEERROR
+           if requested field is an object instance field@endlink.
+ *
+ */
+#define CHECK_STATIC_FIELD                                       \
+                                                                 \
+    /* Must be a static field */                                 \
+    if (!(ACC_STATIC & pfld->access_flags))                      \
+    {                                                            \
+        thread_throw_exception(thridx,                           \
+                               THREAD_STATUS_THREW_ERROR,        \
+               JVMCLASS_JAVA_LANG_INCOMPATIBLECLASSCHANGEERROR); \
+/*NOTREACHED*/                                                   \
+    }
+
+
+/*!
+ * @brief Check if this field is an object instance field.
+ *
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ * @return @link #rvoid rvoid@endlink
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INCOMPATIBLECLASSCHANGEERROR
+ *         @link #JVMCLASS_JAVA_LANG_INCOMPATIBLECLASSCHANGEERROR
+           if requested method is a static field@endlink.
+ *
+ */
+#define CHECK_INSTANCE_FIELD                                     \
+                                                                 \
+    /* Must be an instance field */                              \
+    if (ACC_STATIC & pfld->access_flags)                         \
+    {                                                            \
+        thread_throw_exception(thridx,                           \
+                               THREAD_STATUS_THREW_ERROR,        \
+               JVMCLASS_JAVA_LANG_INCOMPATIBLECLASSCHANGEERROR); \
+/*NOTREACHED*/                                                   \
+    }
+
+
+/*!
+ * @brief Check if this field is a final field in the current class.
+ *
+ *
+ * Determine if a final field is in the current class.  If so, fine,
+ * but otherwise it is in a superclass.  This is an error.
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ * @return @link #rvoid rvoid@endlink
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_ILLEGALACCESSERROR
+ *         @link #JVMCLASS_JAVA_LANG_ILLEGALACCESSERROR
+           if requested field is final, but in a superclass@endlink.
+ *
+ */
+#define CHECK_FINAL_FIELD_CURRENT_CLASS                          \
+                                                                 \
+    {                                                            \
+        jvm_class_index clsidxTMP;                               \
+                                                                 \
+        GET_PC_FIELD(thridx, clsidxTMP, clsidx);                 \
+                                                                 \
+        /* A final field must _not_ be found in a superclass */  \
+        if ((ACC_FINAL & pfld->access_flags) &&                  \
+            (clsidxTMP != pcpd_Fieldref                          \
+                            ->LOCAL_Fieldref_binding.clsidxJVM)) \
+        {                                                        \
+            thread_throw_exception(thridx,                       \
+                                   THREAD_STATUS_THREW_ERROR,    \
+                       JVMCLASS_JAVA_LANG_ILLEGALACCESSERROR);   \
+/*NOTREACHED*/                                                   \
+        }                                                        \
+    }
+
+
+/*!
+ * @brief Check if this field requires two @link #jint jint@endlink
+ * accesses or just one.
+ *
+ *
+ * JVM stack operations and local variable accesses need to know
+ * if the datum to be moved takes one @link #jint jint@endlink slot
+ * or two.  Items of types @link #jlong jlong@endlink and
+ * @link #jdouble jdouble@endlink take two such accesses, all others
+ * take just one.
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if this field takes two
+ * accesses, otherwise @link #rfalse rfalse@endlink for smaller types.
+ *
+ */
+#define CHECK_TWO_ACCESSES                                         \
+                                                                   \
+    (((pcpd_Fieldref->LOCAL_Fieldref_binding.jvaluetypeJVM ==      \
+       BASETYPE_CHAR_J)                                         || \
+      (pcpd_Fieldref->LOCAL_Fieldref_binding.jvaluetypeJVM ==      \
+       BASETYPE_CHAR_D))                                           \
+    ? rtrue                                                        \
+    : rfalse)
+
+
+/*!
+ * @brief Store out value by data type into either class static field
+ * or object instance field.
+ *
+ *
+ * @param data_array  Expression pointing to the class' or object's
+ *                    @b XXX_data[] array, namely a (jvalue *).
+ *                    Typically a fixed set of two expressions.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ *
+ * @see PUTFIELD
+ *
+ * @see PUTSTATIC
+ *
+ *
+ * @todo The various type casting games of integer/sub-integer
+ *       and integer/float/double and integer/objhash need to be
+ *       carefully scrutinized for correctness at run time.
+ *
+ * @todo Is BASTYPE_CHAR_ARRAY a legal case for @b PUTSTATIC and
+ *       @b PUTFIELD ?
+ *
+ */
+#define PUTDATA(data_array)                                            \
+    switch (pcpd_Fieldref->LOCAL_Fieldref_binding.jvaluetypeJVM)       \
+    {                                                                  \
+        case BASETYPE_CHAR_B:                                          \
+            POP(thridx,                                                \
+                data_array._jbyte,                                     \
+                jbyte);                                                \
+            break;                                                     \
+                                                                       \
+        case BASETYPE_CHAR_C:                                          \
+            POP(thridx,                                                \
+                data_array._jchar,                                     \
+                jchar);                                                \
+            break;                                                     \
+                                                                       \
+        case BASETYPE_CHAR_D:                                          \
+            /*                                                         \
+             * DO NOT pop into a 64-bit word!  @link #POP() POP@endlink\
+             * was only designed to operate on 32-bit data types.      \
+             * Instead, use two instances.  Besides, these halves      \
+             * needs to get pushed through bytegames_combine_jdouble() \
+             * anyway to retrieve the final                            \
+             * @link #jdouble jdouble@endlink value.                   \
+             */                                                        \
+            POP(thridx, jitmp2, jint);                                 \
+            POP(thridx, jitmp1, jint);                                 \
+            data_array._jdouble = bytegames_combine_jdouble(jitmp1,    \
+                                                            jitmp2);   \
+            break;                                                     \
+                                                                       \
+        case BASETYPE_CHAR_F:                                          \
+            /*                                                         \
+             * DO NOT pop into a jfloat!  This will consider           \
+             * the source as an integer to be converted instead        \
+             * of a 32-bit floating point word stored in a 32-bit      \
+             * integer word on the stack.  Instead, use the            \
+             * FORCE_JFLOAT() macro to sustain contents across         \
+             * type boundaries.                                        \
+             */                                                        \
+            POP(thridx, jitmp1, jint);                                 \
+            data_array._jfloat = FORCE_JFLOAT(jitmp1);                 \
+            break;                                                     \
+                                                                       \
+        case BASETYPE_CHAR_I:                                          \
+            POP(thridx,                                                \
+                data_array._jint,                                      \
+                /* redundant: */ jint);                                \
+            break;                                                     \
+                                                                       \
+        case BASETYPE_CHAR_J:                                          \
+            /*                                                         \
+             * DO NOT pop into a 64-bit word!  @link #POP() POP@endlink\
+             * was only designed to operate on 32-bit data types.      \
+             * Instead, use two instances.  Besides, these halves      \
+             * needs to get pushed through bytegames_combine_jlong()   \
+             * anyway to retrieve the final                            \
+             * @link #jlong jlong@endlink value.                       \
+             */                                                        \
+            POP(thridx, jitmp2, jint);                                 \
+            POP(thridx, jitmp1, jint);                                 \
+            jltmp = bytegames_combine_jlong(jitmp1, jitmp2);           \
+            data_array._jlong = jltmp;                                 \
+            break;                                                     \
+                                                                       \
+        case BASETYPE_CHAR_L:                                          \
+            POP(thridx,                                                \
+                data_array._jobjhash,                                  \
+                jvm_object_hash);                                      \
+            break;                                                     \
+                                                                       \
+        case BASETYPE_CHAR_S:                                          \
+            POP(thridx,                                                \
+                data_array._jshort,                                    \
+                jshort);                                               \
+            break;                                                     \
+                                                                       \
+        case BASETYPE_CHAR_Z:                                          \
+            POP(thridx,                                                \
+                data_array._jboolean,                                  \
+                jboolean);                                             \
+            break;                                                     \
+                                                                       \
+        case BASETYPE_CHAR_ARRAY:                                      \
+            POP(thridx,                                                \
+                data_array._jarray,                                    \
+                jvm_object_hash);                                      \
+            break;                                                     \
+                                                                       \
+        case LOCAL_BASETYPE_ERROR:                                     \
+        default:                                                       \
+            /* Something is @e very wrong if code gets here */         \
+            thread_throw_exception(thridx,                             \
+                                   THREAD_STATUS_THREW_ERROR,          \
+                                   JVMCLASS_JAVA_LANG_VERIFYERROR);    \
+/*NOTREACHED*/                                                         \
+            break;                                                     \
+    }
+
+
+/*!
+ * @brief Store out value by data type into class static field.
+ *
+ */
+#define PUTSTATIC                                                  \
+    PUTDATA(CLASS(pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM) \
+              .class_static_field_data[fluidxmisc])
+
+
+/*!
+ * @brief Store out value by data type into object instance field.
+ *
+ */
+#define PUTFIELD                                                     \
+     PUTDATA(OBJECT(pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM) \
+               .object_instance_field_data[fluidxmisc])
+
+
+/*!
+ * @brief Retrieve value by data type from either class static field or
+ * object instance field.
+ *
+ *
+ * @param data_array  Expression pointing to the class' or object's
+ *                    @b XXX_data[] array, namely a (jvalue *).
+ *                    Typically a fixed set of two expressions.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ *
+ * @see GETFIELD
+ *
+ * @see GETSTATIC
+ *
+ *
+ * @todo The various type casting games of integer/sub-integer
+ *       and integer/float/double and integer/objhash need to be
+ *       carefully scrutinized for correctness at run time.
+ *
+ * @todo Is BASTYPE_CHAR_ARRAY a legal case for @b GETSTATIC and
+ *       @b GETFIELD ?
+ *
+ */
+#define GETDATA(data_array)                                            \
+    switch (pcpd_Fieldref->LOCAL_Fieldref_binding.jvaluetypeJVM)       \
+    {                                                                  \
+        case BASETYPE_CHAR_B:                                          \
+            PUSH(thridx,                                               \
+                 (jint) data_array._jbyte);                            \
+            break;                                                     \
+                                                                       \
+        case BASETYPE_CHAR_C:                                          \
+            PUSH(thridx,                                               \
+                (jint) data_array._jchar);                             \
+            break;                                                     \
+                                                                       \
+        case BASETYPE_CHAR_D:                                          \
+            bytegames_split_jdouble(data_array._jdouble,               \
+                                    &jitmp1,                           \
+                                    &jitmp2);                          \
+            /*                                                         \
+             * DO NOT push from a 64-bit word! @link #PUSH()           \
+               PUSH@endlink was only designed to operate on 32-bit     \
+             * data types.  Instead, use two instances.                \
+             */                                                        \
+            PUSH(thridx, jitmp1);                                      \
+            PUSH(thridx, jitmp2);                                      \
+            break;                                                     \
+                                                                       \
+        case BASETYPE_CHAR_F:                                          \
+            /*                                                         \
+             * DO NOT pop into a jfloat!  This will consider           \
+             * the source as an integer to be converted instead        \
+             * of a 32-bit floating point word stored in a 32-bit      \
+             * integer word on the stack.  Instead, use the            \
+             * FORCE_JFLOAT() macro to sustain contents across         \
+             * type boundaries.                                        \
+             */                                                        \
+            jitmp1 = FORCE_JINT(data_array._jfloat);                   \
+            PUSH(thridx, jitmp1);                                      \
+            break;                                                     \
+                                                                       \
+        case BASETYPE_CHAR_I:                                          \
+            PUSH(thridx,                                               \
+                 (jint) /* ... redundant */ data_array._jint);         \
+            break;                                                     \
+                                                                       \
+        case BASETYPE_CHAR_J:                                          \
+            bytegames_split_jlong(data_array._jlong,                   \
+                                  &jitmp1,                             \
+                                  &jitmp2);                            \
+            /*                                                         \
+             * DO NOT push from a 64-bit word! @link #PUSH()           \
+               PUSH@endlink was only designed to operate on 32-bit     \
+             * data types.  Instead, use two instances.                \
+             */                                                        \
+            PUSH(thridx, jitmp1);                                      \
+            PUSH(thridx, jitmp2);                                      \
+            break;                                                     \
+                                                                       \
+        case BASETYPE_CHAR_L:                                          \
+            PUSH(thridx,                                               \
+                 (jint) data_array._jobjhash);                         \
+            break;                                                     \
+                                                                       \
+        case BASETYPE_CHAR_S:                                          \
+            PUSH(thridx,                                               \
+                 (jint) data_array._jshort);                           \
+            break;                                                     \
+                                                                       \
+        case BASETYPE_CHAR_Z:                                          \
+            PUSH(thridx,                                               \
+                 (jint) data_array._jboolean);                         \
+            break;                                                     \
+                                                                       \
+        case BASETYPE_CHAR_ARRAY:                                      \
+            PUSH(thridx,                                               \
+                 (jint) data_array._jarray);                           \
+            break;                                                     \
+                                                                       \
+        case LOCAL_BASETYPE_ERROR:                                     \
+        default:                                                       \
+            /* Something is @e very wrong if code gets here */         \
+            thread_throw_exception(thridx,                             \
+                                   THREAD_STATUS_THREW_ERROR,          \
+                                   JVMCLASS_JAVA_LANG_VERIFYERROR);    \
+/*NOTREACHED*/                                                         \
+            break;                                                     \
+    }
+
+
+/*!
+ * @brief Retrieve value by data type from class static field.
+ *
+ */
+#define GETSTATIC                                                  \
+    GETDATA(CLASS(pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM) \
+              .class_static_field_data[fluidxmisc])
+
+
+/*!
+ * @brief Retrieve value by data type from object instance field.
+ *
+ */
+#define GETFIELD                                                    \
+    GETDATA(OBJECT(pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM) \
+              .object_instance_field_data[fluidxmisc])
+
+
+/*@} */ /* End of grouped definitions */
+
+/*!
+ * Handler linkage for end of thread detection.
+ */
+static jmp_buf opcode_end_thread_return;
+
+
+/*!
+ * @brief JVM inner loop setup for end of thread detection-- implements
+ * @c @b setjmp(3) .
+ *
+ *
+ * Use this function to arm handler for non-local exit from the
+ * inner @c @b while() loop when a thread has finished
+ * running.
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ * @returns From normal setup, integer
+ *          @link #EXIT_MAIN_OKAY EXIT_MAIN_OKAY@endlink.
+ *          Otherwise, return
+ *          @link #exit_code_enum exit_enum code enumeration@endlink
+ *          from @link #opcode_end_thread_test()
+            opcode_end_thread_test()@endlink.
+ *
+ */
+
+static int opcode_end_thread_setup(rvoid)
+{
+    /*
+     * Return point from @c @b longjmp(3) as declared
+     * in @link #opcode_end_thread_test()
+       opcode_end_thread_test()@endlink
+     */
+    return(setjmp(opcode_end_thread_return));
+
+} /* END of opcode_end_thread_setup() */
+
+
+/*!
+ * @brief Detect end of thread when stack frame is empty at
+ * @b return time and perform non-local return-- implements
+ * @c @b longjmp(3) .
+ *
+ * Use this function to test for end of thread execution and to
+ * perform a non-local return from the inner @c @b while()
+ * loop when a thread has finished running.
+ *
+ * This function is invoked from within each of the Java
+ * @b return family of opcodes to detect if the stack frame is
+ * empty after a @link #POP_FRAME() POP_FRAME()@endlink.  If this
+ * test passes, then the stack frame is empty and the thread has
+ * nothing else to do.  It is therefore moved into the @b COMPLETE
+ * state and a non-local return exits the while loop.
+ *
+ *
+ * @param thridx  Thread index of thread to evaluate.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink if end of thread test fails.
+ *          If test passes, perform non-local state restoration from
+ *          setup via @c @b setjmp(3) as stored in @link
+            #opcode_end_thread_return opcode_end_thread_return@endlink.
+ *
+ */
+
+static rvoid opcode_end_thread_test(jvm_thread_index thridx)
+{
+    /* Check if thread has finished running */
+
+    /*!
+     * Check both current end of program FP and final FP in case
+     * something like a @c @b \<clinit\> or @c @b \<init\> was loaded
+     * on top of a running program.
+     *
+     * @todo Should FP condition be fp_end_program <= THREAD().fp
+     *       instead of < condition? 
+     *
+     */
+    if (THREAD(thridx).fp_end_program < THREAD(thridx).fp)
+    {
+        /* Thread is still running something, so continue */
+        return;
+    }
+
+    /* Thread has finished running, so return to @c @b setjmp(3) */
+
+    int rc = (int) EXIT_JVM_THREAD;
+    longjmp(opcode_end_thread_return, rc);
+/*NOTREACHED*/
+
+} /* END of opcode_end_thread_test() */
+
+
+/*!
+ * @brief Double-fault error state variable for throwable event.
+ *
+ * This boolean reports the the error-within-an-error state condition
+ * within
+ * @link #rvoid opcode_load_run_throwable()
+   opcode_load_run_throwable()@endlink
+ */
+rboolean opcode_calling_java_lang_linkageerror =
+    CHEAT_AND_USE_FALSE_TO_INITIALIZE;
+
+
+/*!
+ * @brief Load a @c @b java.lang.Throwable event, typically
+ * an @b Error or @b Exception and run its @c @b \<clinit\> method
+ * followed by its @c @b \<init\> method with default parameters.
+ *
+ * This function must @e not be called until
+ * @c @b java.lang.Object , @c @b java.lang.Class,
+ * @c @b java.lang.String , @c @b java.lang.Throwable
+ * @c @b java.lang.Error have been loaded and initialized.
+ *
+ * There is @e no attempt to enforce which classes may be invoked
+ * by this handler.  It is assumed that the caller will @e only
+ * pass in subclasses of
+ * @link #JVMCLASS_JAVA_LANG_ERROR JVMCLASS_JAVA_LANG_ERROR@endlink.
+ * Anything else will produce undefined results.
+ *
+ * @warning <b>This handler is not a simple as it seems!</b>  You
+ * absolutely @e must know what the non-local return mechanism
+ * @c @b setjmp(3)/longjmp(3) is before attempting to figure it out!!!
+ *
+ * The strategy is a simple one:  Trap thrown errors by this handler
+ * and trap a failure in that error class by throwing a @link
+   #JVMCLASS_JAVA_LANG_INTERNALERROR
+   JVMCLASS_JAVA_LANG_INTERNALERROR@endlink.  If that fails, give up.
+ *
+ * @b Details:  When this function is first called due to a thrown
+ * error, it attempts to load and run that error class.  If all
+ * is well, that class runs and everyone lives happily ever after.
+ * If that class throws an error, however, this handler, having
+ * been re-armed, is activated semi-recursively via @link
+   #exit_throw_exception() exit_throw_exception()@endlink,
+ * (that is, not entering at the top of function, but at the return
+ * from @link #exit_throw_exception() exit_throw_exception()@endlink
+ * with a non-zero return value), entering @e this code at
+ * @link #exit_exception_setup exit_exception_setup()@endlink,
+ * choosing the conditional branch != @link #EXIT_MAIN_OKAY
+   EXIT_MAIN_OKAY@endlink and attempts to recursively load and
+ * run @link #JVMCLASS_JAVA_LANG_LINKAGEERROR
+   JVMCLASS_JAVA_LANG_LINKAGEERROR@endlink.  If this is successful,
+ * fine, call @link #exit_jvm() exit_jvm()@endlink and be done.
+ * However, if even @e this fails and throws an error, the handler,
+ * having been rearmed @e again by the attempt to invoke
+ * @link #JVMCLASS_JAVA_LANG_LINKAGEERROR
+   JVMCLASS_JAVA_LANG_LINKAGEERROR@endlink, it again semi-recursively
+ * is activated via @link #exit_throw_exception()
+   exit_throw_exception()@endlink and again enters the code at
+ * @link #exit_exception_setup() exit_exception_setup()@endlink.  This
+ * time, the global
+ * @link #opcode_calling_java_lang_linkageerror
+   opcode_calling_java_lang_linkageerror@endlink is
+ * @link #rtrue rtrue@endlink, so no more recursive invocations
+ * are performed.  Instead, @link #exit_jvm() exit_jvm()@endlink
+ * with the most recent @link #EXIT_MAIN_OKAY EXIT_xxx@endlink code
+ * from @link #exit_throw_exception() exit_throw_exception()@endlink
+ * and be done.
+ *
+ *
+ * @param  pThrowableEvent  Null-terminated string name of
+ *                          throwable class.
+ *
+ * @param  thridx           Thread table index of thread to load this
+ *                          @c @b java.lang.Throwable sub-class
+ *                          into.
+ *
+ *
+ * @returns  @link #rvoid rvoid@endlink.  Either the
+ *           @c @b java.lang.Throwable class loads and
+ *           runs, or it loads @c @b java.lang.LinkageError
+ *           and runs it, then returns to caller, or it exits
+ *           due to an error somewhere in this sequence of
+ *           events.
+ *
+ */
+
+rvoid opcode_load_run_throwable(rchar            *pThrowableEvent,
+                                jvm_thread_index  thridx)
+{
+    /******* Re-arm java.lang.LinkageError handler ***/
+
+
+    /*!
+     * @internal This call to exit_exception_setup() and the following
+     * if (@link #EXIT_MAIN_OKAY EXIT_MAIN_OKAY@endlink) statement
+     * constitute the ugly part of this code as described above.
+     * See also other recursive calls and their control via
+     * @link #opcode_calling_java_lang_linkageerror
+       opcode_calling_java_lang_linkageerror@endlink:
+     *
+     */
+    int nonlocal_rc = exit_exception_setup();
+
+    if (EXIT_MAIN_OKAY != nonlocal_rc)
+    {
+        /*!
+         * @todo  Make this load and run the error class
+         *        @c @b \<clinit\> and default @c @b \<init\> method
+         *        instead of/in addition to fprintf().  Other
+         *        exit_throw_exception() handlers will have invoked
+         *        this method, so it @e must be rearmed @e again at
+         *        this point, lest an error that invokes it causes
+         *        an infinite loop.
+         */
+
+        /* Should never be true via exit_throw_exception() */
+        if (rnull == exit_LinkageError_subclass)
+        {
+            exit_LinkageError_subclass = "unknown";
+        }
+
+        fprintfLocalStderr(
+            "opcode_load_run_throwable:  Recursive Error %d (%s): %s\n",
+            nonlocal_rc,
+            exit_get_name(nonlocal_rc),
+            exit_LinkageError_subclass);
+
+        jvmutil_print_stack(thridx, (rchar *) rnull);
+
+        /*
+         * WARNING!!! Recursive call, but will only go 1 level deep.
+         */
+        if (rfalse == opcode_calling_java_lang_linkageerror)
+        {
+            opcode_calling_java_lang_linkageerror = rtrue;
+
+            opcode_load_run_throwable(JVMCLASS_JAVA_LANG_LINKAGEERROR,
+                                      rtrue);
+
+            opcode_calling_java_lang_linkageerror = rfalse;
+        }
+
+        exit_jvm(nonlocal_rc);
+/*NOTREACHED*/
+    }
+
+    if (jvm_thread_index_null == thridx)
+    {
+        sysErrMsg("opcode_load_run_throwable",
+             "Invalid thread index %d for throwable class %s",
+                thridx, pThrowableEvent);
+        return;
+    }
+
+    /*!
+     * @internal Load error class and run its @c @b \<clinit\> method.
+     *
+     * If an error is thrown by class_load_resolve_clinit(),
+     * re-enter this error function recursively at
+     * exit_exception_setup().
+     */
+    jvm_class_index clsidx =
+        class_load_resolve_clinit(pThrowableEvent,
+                                  thridx,
+                                  rfalse, /* N/A due to valid thridx */
+                                  rfalse);
+
+    /*!
+     * @internal Both mark (here) and unmark (below) class
+     * so it gets garbage collected.
+     */
+    (rvoid) GC_CLASS_MKREF_FROM_CLASS(jvm_class_index_null, clsidx);
+
+
+    /*!
+     * @internal Instantiate error class object and run its default
+     * @c @b \<init\> method with default parameters.
+     *
+     * If an error is thrown in objec_instance_new(), re-enter this
+     * error function recursively at exit_exception_setup().
+     */
+    jvm_object_hash objhash=
+        object_instance_new(THREAD_STATUS_EMPTY,
+                            CLASS_OBJECT_LINKAGE(clsidx)->pcfs,
+                            clsidx,
+                            LOCAL_CONSTANT_NO_ARRAY_DIMS,
+                            (jint *) rnull,
+                            rtrue,
+                            thridx);
+
+    /*!
+     * @internal Both mark and unmark object so it
+     * gets garbage collected
+     */
+    (rvoid) GC_OBJECT_MKREF_FROM_OBJECT(jvm_object_hash_null, objhash);
+    (rvoid) GC_OBJECT_RMREF_FROM_OBJECT(jvm_object_hash_null, objhash);
+
+    /*!
+     * @internal Unmarked from above-- since JVM is going down,
+     * this may be irrelevant, but be consistent.
+     */
+    (rvoid) GC_CLASS_RMREF_FROM_CLASS(jvm_class_index_null, clsidx);
+
+    return;
+
+} /* END of opcode_load_run_throwable() */
+
+
+/*!
+ * @brief Inner loop of JVM virtual instruction execution engine.
+ *
+ * Only run the inner loop until:
+ *
+ * <ul>
+ * <li> thread state changes </li>
+ * <li> time slice expired </li>
+ * <li> thread completes (when FP is not 0, that is,
+ *      not @link #JVMCFG_NULL_SP JVMCFG_NULL_SP@endlink) </li>
+ * </ul>
+ *
+ * Any remaining time on this time slice will go against
+ * the next thread, which may only have a small amount
+ * of time, even none at all.  This is a natural effect
+ * of any time-slicing algorithm.
+ *
+ * Logic similar to the uncaught exception handler of this function
+ * may be found in object_run_method() as far as initiating execution
+ * of a JVM method.
+ *
+ * @todo  See if there is a better time-slicing algorithm that
+ *        is just as easy to use and keeps good real clock time.
+ * 
+ * @todo:  having @c @b run_init_ (parm 7) for invocations of
+ *         opject_instance_new() to be @link #rfalse rfalse@endlink
+ *         the right thing to do for array initialization, namely
+ *         opcodes @b NEWARRAY and @b ANEWARRAY ?  Initializing an
+ *         array is really not a constructor type
+ *         of operation, but the individual components
+ *         (elements) of the array probably would be,
+ *         and with default parameters.
+ *
+ *
+ *
+ * @param  thridx            Thread index of thread to run
+ *
+ * @param  check_timeslice   @link #rtrue rtrue@endlink if JVM time
+ *                           slice preempts execution after maximum
+ *                           time exceeded.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if this method and/or time slice
+ *          ran correctly (whether or not the thread finished running),
+ *          or @link #rfalse rfalse@endlink if an
+ *          uncaught exception was thrown or if an
+ *          Error, Exception, or Throwable was thrown, or if a
+ *          thread state could not be properly changed.
+ *
+ */
+rboolean opcode_run(jvm_thread_index thridx,
+                    rboolean check_timeslice)
+{
+    /*
+     * Arm handler for the three conditions
+     * java.lang.Error, Exception, and Throwable.
+     *
+     * Any JVM virtual execution that throws one of
+     * these that is @e not covered by an exception
+     * handler in the class will issue:
+     *
+     *     <b><code>
+           longjmp(THREAD(thridx).nonlocal_ThrowableEvent, rc)
+           </b></code>
+     *
+     * by way of @link #thread_throw_exception() 
+       thread_throw_exception@endlink, which will return to the
+     * @c @b else branch of this @c @b if .  It will
+     * contain a @link rthread#status (rthread.status@endlink bit
+     * @b THREAD_STATUS_xxx which may be examined there.  Notice that
+     * @c @b int is wider than @c @b rushort and thus
+     * will not lose any information in the implicit conversion.
+     */
+
+    /* Inner loop end of thread detection, init to unused value */
+    int nonlocal_thread_return = EXIT_JVM_INTERNAL;
+
+    /* Calls @c @b setjmp(3) to arm handler */
+    int nonlocal_rc = thread_exception_setup(thridx);
+
+    /* Show error case first due to @e long switch() following */
+    if (THREAD_STATUS_EMPTY != nonlocal_rc)
+    {
+        /*
+         * Examine only the @c @b longjmp(3) conditions (should be
+         * irrelevant due to filter in @link #thread_throw_exception()
+           thread_throw_exception()@endlink
+         */
+        nonlocal_rc &= (THREAD_STATUS_THREW_EXCEPTION |
+                        THREAD_STATUS_THREW_ERROR |
+                        THREAD_STATUS_THREW_THROWABLE |
+                        THREAD_STATUS_THREW_UNCAUGHT);
+
+        /*
+         * Local copy of @link rthread#pThrowable pThrowable@endlink
+         * for use below
+         */
+        rchar *pThrowableEvent = THREAD(thridx).pThrowableEvent;
+
+        /*
+         * Clear out the Throwable condition now that it
+         * is being processed, in case of multiple exceptions.
+         */
+        THREAD(thridx).pThrowableEvent = (rchar *) rnull;
+        THREAD(thridx).status &= ~(THREAD_STATUS_THREW_EXCEPTION |
+                                   THREAD_STATUS_THREW_ERROR |
+                                   THREAD_STATUS_THREW_THROWABLE |
+                                   THREAD_STATUS_THREW_UNCAUGHT);
+
+        /*
+         * Process the specifics for each java.lang.Throwable
+         * condition before doing the generic processing.
+         */
+        if (THREAD_STATUS_THREW_EXCEPTION & nonlocal_rc)
+        {
+            /*! @todo  What needs to go here? */
+        }
+        else
+        if (THREAD_STATUS_THREW_ERROR & nonlocal_rc)
+        {
+            /*! @todo  What needs to go here? */
+        }
+        else
+        if (THREAD_STATUS_THREW_THROWABLE & nonlocal_rc)
+        {
+            /*! @todo  What needs to go here? */
+        }
+        else
+        if (THREAD_STATUS_THREW_UNCAUGHT & nonlocal_rc)
+        {
+            /*
+             * Handle an uncaught exception.  @b pThrowableEvent will
+             * be @link #rnull rnull@endlink here, so there is nothing
+             * to get from it.
+             */
+
+            jvm_class_index clsidx = class_find_by_prchar(
+                                        JVMCLASS_JAVA_LANG_THREADGROUP);
+
+            if (jvm_class_index_null == clsidx)
+            {
+                /* Problem creating error class, so quit */
+                sysErrMsg("opcode_run",
+                     "Cannot find class %s",
+                     JVMCLASS_JAVA_LANG_THREADGROUP);
+
+                jvmutil_print_stack(thridx, (rchar *) rnull);
+
+                exit_jvm(EXIT_JVM_CLASS);
+/*NOTREACHED*/
+            }
+
+            /*!
+             * @todo Get @c @b ThreadGroup logic working that
+             * figures out which @c @b java.lang.ThreadGroup
+             * this thread is a part of and invoke
+             * @c @b java.lang.ThreadGroup.uncaughtException()
+             * for that specific object instead of this general method.
+             * Probably the class library will gripe about not knowing
+             * which object to associate with the method call since
+             * @c @b java.lang.ThreadGroup.uncaughtException()
+             * is @e not a @c @b static method.
+             */
+
+            /*
+             * Set FP lower boundary so Java @c @b return
+             * instruction does not keep going after handler, check if
+             * @c @b java.lang.ThreadGroup.uncaughtException()
+             * is there, and run it.
+             */
+            jvm_sp fp_save_end_program = THREAD(thridx).fp_end_program;
+
+            /*
+             * Make JVM stop once
+             * @c @b java.lang.ThreadGroup.uncaughtException()
+             * is done
+             */
+            THREAD(thridx).fp_end_program = THREAD(thridx).fp;
+
+            /* Continue getting pieces for PUT_PC_IMMEDIATE() */
+            jvm_method_index mthidx =
+                method_find_by_prchar(clsidx,
+                                      JVMCFG_UNCAUGHT_EXCEPTION_METHOD,
+                                      JVMCFG_UNCAUGHT_EXCEPTION_PARMS);
+
+            if (jvm_method_index_bad == mthidx)
+            {
+                exit_throw_exception(EXIT_JVM_METHOD,
+                                  JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
+/*NOTREACHED*/
+            }
+
+            /*
+             * Load up entry point for Throwable call
+             */
+            ClassFile *pcfs = CLASS_OBJECT_LINKAGE(clsidx)->pcfs;
+
+            jvm_attribute_index codeatridx =
+                pcfs->methods[mthidx]
+                        ->LOCAL_method_binding.codeatridxJVM;
+
+            if (jvm_attribute_index_bad == codeatridx)
+            {
+                exit_throw_exception(EXIT_JVM_ATTRIBUTE,
+                                  JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
+/*NOTREACHED*/
+            }
+
+            if (jvm_attribute_index_native == codeatridx)
+            {
+                /* Pass parameters for both local method and JNI call */
+                native_run_method(thridx,
+                                  pcfs
+                                    ->methods[mthidx]
+                                      ->LOCAL_method_binding.nmordJVM,
+                                  clsidx,
+                                  pcfs->methods[mthidx]->name_index,
+                                  pcfs->methods[mthidx]
+                                    ->descriptor_index);
+            }
+            else
+            {
+                Code_attribute *pca = (Code_attribute *)
+                         &pcfs->methods[mthidx]->attributes[codeatridx];
+                PUSH_FRAME(thridx, pca->max_locals);
+                PUT_PC_IMMEDIATE(thridx,
+                                 clsidx,
+                                 mthidx,
+                                 pcfs
+                                   ->methods[mthidx]
+                                   ->LOCAL_method_binding.codeatridxJVM,
+                                 pcfs
+                                   ->methods[mthidx]
+                                   ->LOCAL_method_binding.excpatridxJVM,
+                                 CODE_CONSTRAINT_START_PC);
+
+                if (rfalse == opcode_run(thridx, rfalse))
+                {
+                    /* Problem running error class, so quit */
+                    sysErrMsg("opcode_run",
+                              "Cannot run exception method %s %s%s",
+                              JVMCLASS_JAVA_LANG_THREADGROUP,
+                              JVMCFG_UNCAUGHT_EXCEPTION_METHOD,
+                              JVMCFG_UNCAUGHT_EXCEPTION_PARMS);
+
+                    jvmutil_print_stack(thridx, (rchar *) rnull);
+
+                    exit_jvm(EXIT_JVM_THREAD);
+/*NOTREACHED*/
+                }
+            }
+
+            /*
+             * This would normally permit java.lang.Exception 
+             * and java.lang.Throwable to continue by restoring
+             * lower FP boundary, but unwind here anyway for
+             * proper frame contents for later diagnostics.
+             */
+            THREAD(thridx).fp_end_program = fp_save_end_program;
+
+            /* Attempt to shut down thread due to condition */
+            if (rfalse == threadstate_request_complete(thridx))
+            {
+                sysErrMsg("opcode_run",
+                 "Unable to move completed thread %d to '%s' state",
+                          thridx,
+                          thread_state_get_name(THREAD_STATE_COMPLETE));
+                THREAD_REQUEST_NEXT_STATE(badlogic, thridx);
+
+                return(rfalse);
+            }
+
+            return(rfalse);
+
+        } /* if THREAD_STATUS_THREW_UNCAUGHT */
+        else
+        {
+            /*! @todo  What needs to go here, if anything? */
+        }
+
+        /* Completely handled THREAD_STATUS_THREW_UNCAUGHT above */
+        if (nonlocal_rc & (THREAD_STATUS_THREW_EXCEPTION |
+                           THREAD_STATUS_THREW_ERROR |
+                           THREAD_STATUS_THREW_THROWABLE))
+        {
+            /*
+             * Utilizing the current contents of the @c @b longjmp(3)
+             * condition found in @b pThrowableEvent, which will
+             * have been set when one of the status bits was set--
+             * see @link jvm/src/threadutil.c threadutil.c@endlink
+             * for several examples.
+             *
+             * When loading the error class, process its
+             * @c @b \<clinit\> on any available thread, but process
+             * its @C @b \<init\> on @e this thread so thread will be
+             * done running after it has been processed (due to FP
+             * change).
+             */
+            opcode_load_run_throwable(pThrowableEvent, thridx);
+
+            /*
+             * All conditions except java.lang.Exception should kill
+             * the thread.
+             *
+             */
+            if (!(THREAD_STATUS_THREW_EXCEPTION & nonlocal_rc))
+            {
+                /* Attempt to shut down thread due to code completion */
+                if (rfalse == threadstate_request_complete(thridx))
+                {
+                    sysErrMsg("opcode_run",
+                     "Unable to move aborted thread %d to '%s' state",
+                              thridx,
+                              thread_state_get_name(
+                                                THREAD_STATE_COMPLETE));
+                    THREAD_REQUEST_NEXT_STATE(badlogic, thridx);
+
+                    return(rfalse);
+                }
+            }
+
+        } /* if nonlocal_rc */
+
+    } /* if thread_exception_setup() */
+    /***************************************************************/
+    /***************************************************************/
+    /***************************************************************/
+    /***************************************************************/
+    /***************************************************************/
+    /* BEGIN GIANT SWITCH STATEMENT if(){}else{while(){switch()}} **/
+    /***************************************************************/
+    /***************************************************************/
+    /***************************************************************/
+    /***************************************************************/
+    /***************************************************************/
+    else
+    {
+        /*
+         * Run inner JVM execution loop.
+         */
+
+        /*
+         * Scratch area for operating the inner loop
+         * and its key associations
+         */
+        jvm_pc             *pc    = THIS_PC(thridx);
+        ClassFile          *pcfs  = THIS_PCFS(thridx);
+        jvm_virtual_opcode *pcode = DEREFERENCE_PC_CODE_BASE(thridx);
+
+        /* Scratch area for operand resolution */
+        rboolean           iswide;
+        iswide = rfalse;
+
+        jvm_virtual_opcode opcode;
+        u1                 op1u1idx; /* Operand 1 as a (u1) CP index */
+        u2                 op1u2idx; /* Operand 1 as a (u2) CP index */
+        u4                 op1u4off; /* Operand 1 as a (u4) offset */
+
+        jint               jitmp1;  /* Opcode (jint) scratch area 1 */
+        jint               jitmp2;  /* Opcode (jint) scratch area 2 */
+        jlong              jltmp;   /* Opcode (jlong) scratch area */
+        jfloat             jftmp;   /* Opcode (jfloat) scratch area */
+        jdouble            jdtmp;   /* Opcode (jdouble) scratch area */
+
+
+        /* Scratch area for Fieldref and Methodref navigation */
+        cp_info_dup               *pcpd;
+        CONSTANT_Class_info       *pcpd_Class;
+        CONSTANT_Fieldref_info    *pcpd_Fieldref;
+        CONSTANT_Methodref_info   *pcpd_Methodref;
+        CONSTANT_NameAndType_info *pcpd_NameAndType;
+        CONSTANT_Utf8_info        *pcpd_Utf8;
+
+        field_info              *pfld;
+        method_info             *pmth;
+
+        ClassFile              *pcfsmisc;
+        u2                      cpidxmisc;
+        jvm_class_index         clsidxmisc;
+        jvm_method_index        mthidxmisc;
+        jvm_object_hash         objhashmisc;
+        jvm_field_lookup_index  fluidxmisc;
+        rchar                   *prchar_clsname;
+        rushort                 special_obj_misc;
+
+
+        /* Calls @c @b setjmp(3) to arm handler */
+        nonlocal_thread_return = opcode_end_thread_setup();
+
+        /* Show error case first due to @e long switch() following */
+        if (EXIT_MAIN_OKAY != nonlocal_thread_return)
+        {
+            ; /* Nothing to do since this is not an error. */
+        }
+        else
+        {
+
+            /*!
+             * @internal For best runtime efficiency, place tests in
+             * order of most to least frequent occurrence.
+             */
+
+            while ( /* This thread is in the RUNNING state */
+                   (THREAD_STATE_RUNNING == THREAD(thridx).this_state)&&
+
+                   /* Time slice is still running or is N/A */
+                   ((rfalse == check_timeslice) || /* or if true and */
+                    (rfalse == pjvm->timeslice_expired)))
+            {
+                /* Retrieve next virtual opcode */
+                opcode = pcode[pc->offset++];
+
+/*
+ * Due to the significant complexity of this @c @b switch
+ * statement, the indentation is being reset to permit wider lines
+ * of code with out breaking up expressions with the intention of
+ * creating better readability of the code.
+ */
+
+static void dummy1(void) { char *p, *dummy2; dummy2 = p; dummy1(); }
+#define STUB { dummy1(); }
+
+switch(opcode)
+{
+case OPCODE_00_NOP:         /* Do nothing */
+    break;
+
+case OPCODE_01_ACONST_NULL: /* Push NULL onto stack */
+    /*! @todo Test this opcode */
+    STUB;
+    PUSH(thridx, FORCE_JINT(jvm_object_hash_null));
+    break;
+
+case OPCODE_02_ICONST_M1:   /* Push constant -1, 0, 1, 2, 3, 4, 5 */
+case OPCODE_03_ICONST_0:
+case OPCODE_04_ICONST_1:
+case OPCODE_05_ICONST_2:
+case OPCODE_06_ICONST_3:
+case OPCODE_07_ICONST_4:
+case OPCODE_08_ICONST_5:
+    PUSH(thridx, (((jint) opcode) - ((jint) OPCODE_03_ICONST_0)));
+    break;
+
+case OPCODE_09_LCONST_0:
+case OPCODE_0A_LCONST_1:
+    /*! @todo Test this opcode */
+    STUB;
+    jltmp = (((jlong) opcode) - ((jlong) OPCODE_09_LCONST_0));
+
+    bytegames_split_jlong(jltmp, &jitmp1, &jitmp2);
+
+    PUSH(thridx, jitmp1); /* ms word */
+    PUSH(thridx, jitmp2); /* ls word */
+    break;
+
+case OPCODE_0B_FCONST_0:
+case OPCODE_0C_FCONST_1:
+case OPCODE_0D_FCONST_2:
+    /*! @todo Test this opcode */
+    STUB;
+    jftmp = (jfloat) (((jint) opcode) - ((jint) OPCODE_0B_FCONST_0));
+
+    PUSH(thridx, FORCE_JINT(jftmp));
+    break;
+
+case OPCODE_0E_DCONST_0:
+case OPCODE_0F_DCONST_1:
+    /*! @todo Test this opcode */
+    STUB;
+    jdtmp = (jdouble) (((jint) opcode) - ((jint) OPCODE_0E_DCONST_0));
+
+    bytegames_split_jdouble(jltmp, &jitmp1, &jitmp2);
+
+    PUSH(thridx, jitmp1); /* ms word */
+    PUSH(thridx, jitmp2); /* ls word */
+
+    break;
+
+case OPCODE_10_BIPUSH:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_11_SIPUSH:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_12_LDC:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_13_LDC_W:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_14_LDC2_W:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_15_ILOAD:
+    /*! @todo Write this opcode */
+    STUB;
+    iswide = rfalse;
+    break;
+
+case OPCODE_16_LLOAD:
+    /*! @todo Write this opcode */
+    STUB;
+    iswide = rfalse;
+    break;
+
+case OPCODE_17_FLOAD:
+    /*! @todo Write this opcode */
+    STUB;
+    iswide = rfalse;
+    break;
+
+case OPCODE_18_DLOAD:
+    /*! @todo Write this opcode */
+    STUB;
+    iswide = rfalse;
+    break;
+
+case OPCODE_19_ALOAD:
+    /*! @todo Write this opcode */
+    STUB;
+    iswide = rfalse;
+    break;
+
+case OPCODE_1A_ILOAD_0:
+case OPCODE_1B_ILOAD_1:
+case OPCODE_1C_ILOAD_2:
+case OPCODE_1D_ILOAD_3:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_1E_LLOAD_0:
+case OPCODE_1F_LLOAD_1:
+case OPCODE_20_LLOAD_2:
+case OPCODE_21_LLOAD_3:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_22_FLOAD_0:
+case OPCODE_23_FLOAD_1:
+case OPCODE_24_FLOAD_2:
+case OPCODE_25_FLOAD_3:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_26_DLOAD_0:
+case OPCODE_27_DLOAD_1:
+case OPCODE_28_DLOAD_2:
+case OPCODE_29_DLOAD_3:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_2A_ALOAD_0:
+case OPCODE_2B_ALOAD_1:
+case OPCODE_2C_ALOAD_2:
+case OPCODE_2D_ALOAD_3:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_2E_IALOAD:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_2F_LALOAD:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_30_FALOAD:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_31_DALOAD:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_32_AALOAD:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_33_BALOAD:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_34_CALOAD:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_35_SALOAD:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_36_ISTORE:
+    /*! @todo Write this opcode */
+    STUB;
+    iswide = rfalse;
+    break;
+
+case OPCODE_37_LSTORE:
+    /*! @todo Write this opcode */
+    STUB;
+    iswide = rfalse;
+    break;
+
+case OPCODE_38_FSTORE:
+    /*! @todo Write this opcode */
+    STUB;
+    iswide = rfalse;
+    break;
+
+case OPCODE_39_DSTORE:
+    /*! @todo Write this opcode */
+    STUB;
+    iswide = rfalse;
+    break;
+
+case OPCODE_3A_ASTORE:
+    /*! @todo Write this opcode */
+    STUB;
+    iswide = rfalse;
+    break;
+
+case OPCODE_3B_ISTORE_0:
+case OPCODE_3C_ISTORE_1:
+case OPCODE_3D_ISTORE_2:
+case OPCODE_3E_ISTORE_3:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_3F_LSTORE_0:
+case OPCODE_40_LSTORE_1:
+case OPCODE_41_LSTORE_2:
+case OPCODE_42_LSTORE_3:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_43_FSTORE_0:
+case OPCODE_44_FSTORE_1:
+case OPCODE_45_FSTORE_2:
+case OPCODE_46_FSTORE_3:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_47_DSTORE_0:
+case OPCODE_48_DSTORE_1:
+case OPCODE_49_DSTORE_2:
+case OPCODE_4A_DSTORE_3:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_4B_ASTORE_0:
+case OPCODE_4C_ASTORE_1:
+case OPCODE_4D_ASTORE_2:
+case OPCODE_4E_ASTORE_3:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_4F_IASTORE:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_50_LASTORE:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_51_FASTORE:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_52_DASTORE:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_53_AASTORE:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_54_BASTORE:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_55_CASTORE:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_56_SASTORE:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_57_POP:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_58_POP2:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_59_DUP:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_5A_DUP_X1:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_5B_DUP_X2:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_5C_DUP2:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_5D_DUP2_X1:
+    /*! @todo Write this opcode */
+    STUB;
+    break;
+
+case OPCODE_5E_DUP2_X2:
+    /*! @todo Write this opcode */

[... 1043 lines stripped ...]