Main Page | Namespace List | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

opcode.c

Go to the documentation of this file.
00001 /*!
00002  * @file opcode.c
00003  *
00004  * @brief Java Virtual Machine inner loop virtual instruction execution.
00005  *
00006  * A specific group of exceptions that may be thrown by JVM execution
00007  * (spec section 2.16.4 unless specified otherwise) are not typically
00008  * checked by the Java program and stop thread execution unless caught
00009  * by a Java @c @b catch block.
00010  *
00011  * <ul>
00012  * <li>
00013  * @b ArithmeticException    Integer divide by zero
00014  * </li><li>
00015  * @b ArrayStoreException    Storage compatibility error between
00016  *                           array type lvalue vs component rvalue
00017  * </li><li>
00018  * @b ClassCastException     Type narrowing loses significance or
00019  *                           casting of an object to a type that
00020  *                           is not valid.
00021  * </li><li>
00022  * @b IllegalMonitorStateException  Thread attempted to wait() or
00023  *                           notify()  on an object that it has
00024  *                           not locked.
00025  * </li><li>
00026  * @b IndexOutOfBoundsException An index or a subrange was outside the
00027  *                           limits >=0 unto < lenghth/size for
00028  *                           an array, string, or vector.
00029  * </li><li>
00030  * @b NegativeArraySizeException Attempted to create an array with a
00031  *                           negative number of elements.
00032  * 
00033  * </li><li>
00034  * @b NullPointerException   An object reference to a
00035  *                           @link #jvm_object_hash_null
00036                              jvm_object_hash_null@endlink object
00037  *                           was attempted instead of to a real
00038  *                           and valid object.
00039  *
00040  * </li><li>
00041  * @b SecurityException      Violation of security policy.
00042  * </li>
00043  * </ul>
00044  *
00045  *
00046  *
00047  * A suite of errors may also be thrown that Java programs normally
00048  * to not attempt to @c @b catch and which terminate JVM
00049  * execution:
00050  *
00051  * <ul>
00052  * <li>
00053  * @link #JVMCLASS_JAVA_LANG_LINKAGEERROR LinkageError@endlink Loading,
00054  *                    linking, or initialization error
00055  *                    (2.17.2, 2.17.3, 2.17.4).  May also be
00056  *                    thrown at run time.
00057  * </li>
00058  *
00059  * <li>
00060  * Loading Errors (2.17.2):
00061  * <ul>
00062  *     <li>
00063  *     @b ClassFormatError        Binary data is not a valid class file.
00064  *     </li><li>
00065  *     @b ClassCircularityError   Class hierarchy eventually references
00066  *                                itself.
00067  *     </li><li>
00068  *     @b NoClassDefFoundError    Class cannot be found by loader.
00069  *     </li><li>
00070  *     @b UnsupportedClassVersionError JVM does not support this version
00071  *                                of the class file specification.
00072  *     </li>
00073  * </ul>
00074  * </li>
00075  *
00076  * <li>
00077  * Linking Errors (2.17.3) (subclass of @link
00078    #JVMCLASS_JAVA_LANG_INCOMPATIBLECLASSCHANGEERROR 
00079    IncompatibleClassChangeError@endlink):
00080  * <ul>
00081  *     <li>
00082  *     @b NosuchFieldError      Attempt to reference non-existent field
00083  *     </li><li>
00084  *     @b NoSuchMethodError     Attempt to reference non-existent method
00085  *     </li><li>
00086  *     @b InstantiationError    Attempt to instantiate abstract class
00087  *     </li><li>
00088  *     @b IllegalAccessError    Attempt to reference a field or method
00089  *                              that is not in scope (typically not
00090  *                              not @c @b public ).
00091  *     </li>
00092  * </ul>
00093  * </li>
00094  *
00095  * <li>
00096  * Verification Errors (2.17.3):
00097  * <ul>
00098  *     <li>
00099  *     @b VerifyError    Class fails integrity checks of the verifier.
00100  *     </li>
00101  * </ul>
00102  * </li>
00103  *
00104  * <li>
00105  * Initialization Errors (2.17.4):
00106  * <ul>
00107  *     <li>
00108  *     @b ExceptionInInitializerError   A static initializer of a static
00109  *                                   field initializer threw something
00110  *                                   that was neither a
00111  *                                   @c @b java.lang.Error
00112  *                                   or its subclass.
00113  *     </li>
00114  * </ul>
00115  * </li>
00116  *
00117  * <li>
00118  * Run-time instances of @link #JVMCLASS_JAVA_LANG_LINKAGEERROR
00119    LinkageError@endlink:
00120  * <ul>
00121  *     <li>
00122  *     @b AbstractMethodError    Invocation of an abstract method.
00123  *     </li><li>
00124  *     @b UnsatisfiedLinkError   Cannot load native method (shared obj).
00125  *     </li>
00126  * </ul>
00127  * </li>
00128  *
00129  * <li>
00130  * Resource limitations, via subclass of @link
00131    #JVMCLASS_JAVA_LANG_VIRTUALMACHINEERROR VirtualMachineError@endlink:
00132  * <ul>
00133  *     <li>
00134  *     @b InternalError         JVM software or host software/hardware
00135  *                              (may occur asynchronously, any time)
00136  *     </li><li>
00137  *     @b OutOfMemoryError      JVM cannot get enough memory for
00138  *                              request, even after GC/mmgmt.
00139  *     </li><li>
00140  *     @b StackOverflowError    Out of JVM stack space, typically due
00141  *                              to infinite recursion on a method.
00142  *     </li><li>
00143  *     @b UnknownError          JVM cannot determine the actual cause.
00144  *     </li>
00145  * </ul>
00146  * </li>
00147  * </ul>
00148  *
00149  *
00150  * @todo The code fragment macros used by the opcode switch in
00151  * @link #opcode_run() opcode_run()@endlink need to have the
00152  * local variables documented as to which as required upon
00153  * macro startup and which are set for use at macro completion.
00154  *
00155  *
00156  * @section Control
00157  *
00158  * \$URL: https://svn.apache.org/path/name/opcode.c $ \$Id: opcode.c 0 09/28/2005 dlydick $
00159  *
00160  * Copyright 2005 The Apache Software Foundation
00161  * or its licensors, as applicable.
00162  * 
00163  * Licensed under the Apache License, Version 2.0 ("the License");
00164  * you may not use this file except in compliance with the License.
00165  * You may obtain a copy of the License at
00166  * 
00167  *     http://www.apache.org/licenses/LICENSE-2.0
00168  * 
00169  * Unless required by applicable law or agreed to in writing,
00170  * software distributed under the License is distributed on an
00171  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
00172  * either express or implied.
00173  * 
00174  * See the License for the specific language governing permissions
00175  * and limitations under the License.
00176  *
00177  * @version \$LastChangedRevision: 0 $
00178  *
00179  * @date \$LastChangedDate: 09/28/2005 $
00180  *
00181  * @author \$LastChangedBy: dlydick $
00182  *         Original code contributed by Daniel Lydick on 09/28/2005.
00183  *
00184  * @section Reference
00185  *
00186  */
00187 
00188 #include "arch.h"
00189 ARCH_COPYRIGHT_APACHE(opcode, c, "$URL: https://svn.apache.org/path/name/opcode.c $ $Id: opcode.c 0 09/28/2005 dlydick $");
00190 
00191 #include "jvmcfg.h"
00192 #include "cfmacros.h"
00193 #include "classfile.h"
00194 #include "exit.h"
00195 #include "gc.h" 
00196 #include "jvm.h"
00197 #include "jvmclass.h"
00198 #include "linkage.h"
00199 #include "method.h"
00200 #include "native.h"
00201 #include "opcode.h"
00202 #include "utf.h"
00203 #include "util.h"
00204 
00205 /*!
00206  * @name Macro support for inner loop opcodes.
00207  *
00208  * @brief Common operations that are used in numerous opcodes
00209  * are gathered here so as to improve accuracy of implementation
00210  * and simplify the code.
00211  *
00212  */
00213 
00214 /*@{ */ /* Begin grouped definitions */
00215 
00216 /*!
00217  * @brief Retrieve a two-byte operand that the PC points to.
00218  *
00219  *
00220  * Store thw two-byte operand into the requested @link #u2 u2@endlink
00221  * variable, then increment the program counter to the next byte code
00222  * following it.
00223  *
00224  * @param u2var  Name of a @link #u2 u2@endlink variable that will
00225  *               receive the two bytes of operand from with the
00226  *               instruction.
00227  *
00228  *
00229  * @returns @link #rvoid rvoid@endlink
00230  *
00231  */
00232 #define GET_U2_OPERAND(u2var)                  \
00233     u2var = GETRS2((u2 *) &pcode[pc->offset]); \
00234     pc->offset += sizeof(u2)
00235  
00236 
00237 /*!
00238  * @name Validate a constant_pool entry
00239  *
00240  */
00241 
00242 
00243 /*@{ */ /* Begin grouped definitions */
00244 
00245 /*!
00246  * @brief Check that a constant_pool entry contains
00247  * a specific of tag for this operation.
00248  *
00249  *
00250  * @param u2var  Name of a @link #u2 u2@endlink variable that
00251  *               contains a constant_pool entry to be examined.
00252  *
00253  * @param cptag1 First constant_pool tag that is valid for this
00254  *               operation.
00255  *
00256  *
00257  * @returns @link #rvoid rvoid@endlink
00258  *
00259  *
00260  * @throws JVMCLASS_JAVA_LANG_VERIFYERROR
00261  *         @link #JVMCLASS_JAVA_LANG_VERIFYERROR
00262          if the constant_pool entry does not have the right tag@endlink.
00263  *
00264  */
00265 #define CHECK_CP_TAG(u2var, cptag1)                             \
00266     if (cptag1 != CP_TAG(pcfs, u2var))                          \
00267     {                                                           \
00268         /* Somebody is confused */                              \
00269         thread_throw_exception(thridx,                          \
00270                                THREAD_STATUS_THREW_ERROR,       \
00271                                JVMCLASS_JAVA_LANG_VERIFYERROR); \
00272 /*NOTREACHED*/                                                  \
00273     }
00274 
00275 
00276 /*!
00277  * @brief Check that a constant_pool entry contains
00278  * the right kind of tag for this operation, from a choice of two.
00279  *
00280  *
00281  * @param u2var  Name of a @link #u2 u2@endlink variable that
00282  *               contains a constant_pool entry to be examined.
00283  *
00284  * @param cptag1 First constant_pool tag that is valid for this
00285  *               operation.
00286  *
00287  * @param cptag2 Second constant_pool tag that is valid for this
00288  *               operation.
00289  *
00290  *
00291  * @returns @link #rvoid rvoid@endlink
00292  *
00293  *
00294  * @throws JVMCLASS_JAVA_LANG_VERIFYERROR
00295  *         @link #JVMCLASS_JAVA_LANG_VERIFYERROR
00296          if the constant_pool entry does not have the right tag@endlink.
00297  *
00298  */
00299 #define CHECK_CP_TAG2(u2var, cptag1, cptag2)                    \
00300     if ((cptag1 != CP_TAG(pcfs, u2var)) &&                      \
00301         (cptag2 != CP_TAG(pcfs, u2var)))                        \
00302     {                                                           \
00303         /* Somebody is confused */                              \
00304         thread_throw_exception(thridx,                          \
00305                                THREAD_STATUS_THREW_ERROR,       \
00306                                JVMCLASS_JAVA_LANG_VERIFYERROR); \
00307 /*NOTREACHED*/                                                  \
00308     }
00309 
00310 
00311 /*!
00312  * @brief Check that a constant_pool entry contains
00313  * the right kind of tag for this operation, from a choice of three.
00314  *
00315  *
00316  * @param u2var  Name of a @link #u2 u2@endlink variable that
00317  *               contains a constant_pool entry to be examined.
00318  *
00319  * @param cptag1 First constant_pool tag that is valid for this
00320  *               operation.
00321  *
00322  * @param cptag2 Second constant_pool tag that is valid for this
00323  *               operation.
00324  *
00325  * @param cptag3 Third constant_pool tag that is valid for this
00326  *               operation.
00327  *
00328  *
00329  * @returns @link #rvoid rvoid@endlink
00330  *
00331  *
00332  * @throws JVMCLASS_JAVA_LANG_VERIFYERROR
00333  *         @link #JVMCLASS_JAVA_LANG_VERIFYERROR
00334          if the constant_pool entry does not have the right tag@endlink.
00335  *
00336  */
00337 #define CHECK_CP_TAG3(u2var, cptag1, cptag2, cptag3)            \
00338     if ((cptag1 != CP_TAG(pcfs, u2var)) &&                      \
00339         (cptag2 != CP_TAG(pcfs, u2var)) &&                      \
00340         (cptag3 != CP_TAG(pcfs, u2var)))                        \
00341     {                                                           \
00342         /* Somebody is confused */                              \
00343         thread_throw_exception(thridx,                          \
00344                                THREAD_STATUS_THREW_ERROR,       \
00345                                JVMCLASS_JAVA_LANG_VERIFYERROR); \
00346 /*NOTREACHED*/                                                  \
00347     }
00348 
00349 /*@} */ /* End of grouped definitions */
00350 
00351 /*!
00352  * @brief Force conversion of any Java type variable
00353  * of @c @b sizeof(jint) into a @link #jint jint@endlink
00354  * variable, but without conversion of contents.
00355  *
00356  *
00357  * This macro is typically used to move a
00358  * @link #jvm_object_hash jobject@endlink reference or a
00359  * @link #jfloat jfloat@endlink into a @link #jint jint@endlink
00360  * word, but suppress type conversion between the
00361  * source and destination variables.  It derives the
00362  * address of the 32-bit source value, casts it as a
00363  * pointer to the destination data type, then extracts
00364  * that type.
00365  *
00366  * @warning This macro @e must have a 32-bit word as its source.
00367  *          For use with smaller types, perform a widening conversion
00368  *          first (such as @link #jboolean jboolean@endlink) to
00369  *          @link #jint jint@endlink.  Then and only then will
00370  *          the target type work correctly.
00371  *
00372  * @warning Since this macro takes the address of its source parameter,
00373  * it will only work for variables, not for expressions!
00374  *
00375  *
00376  * @param var_sizeofjint  Any 32-bit variable.  If it is a smaller
00377  *                        type, such as (jboolean), perform a
00378  *                        widening conversion into (jint) first.
00379  *
00380  * @returns (jint) version of @b var_sizeofjint without conversion
00381  *          of contents (such as jfloat-to-jint might want to do).
00382  *
00383  *
00384  * @todo A careful review of this macro across different compilers
00385  *       is very much in order.
00386  *
00387  */
00388 #define FORCE_JINT(var_sizeofjint) \
00389     (*((jint *) ((jvoid *) &var_sizeofjint)))
00390 
00391 
00392 /*!
00393  * @brief Force conversion of any Java type variable
00394  * of @c @b sizeof(jint) into a @link #jfloat jfloat@endlink
00395  * variable, but without conversion of contents.
00396  *
00397  *
00398  * This macro is typically used to move a
00399  * @link #jint jint@endlink into a @link #jint jint@endlink
00400  * word, but suppress type conversion between the
00401  * source and destination variables.
00402  *
00403  * @warning For comments on the dangers of using this macro,
00404  *          please refer to @link #FORCE_JINT() FORCE_JINT()@endlink.
00405  *
00406  *
00407  * @param var_sizeofjint  Any 32-bit variable.
00408  *
00409  * @returns (jfloat) version of @b var_sizeofjint without conversion
00410  *          of contents (such as jint-to-jfloat might want to do).
00411  *
00412  *
00413  * @todo A careful review of this macro across different compilers
00414  *       is very much in order.
00415  *
00416  */
00417 #define FORCE_JFLOAT(var_sizeofjint) \
00418     (*((jfloat *) ((jvoid *) &var_sizeofjint)))
00419 
00420 
00421 /*!
00422  * @brief Calculate method_info pointer from program counter
00423  *
00424  * During the calculation, various scratch variables are
00425  * loaded and used to simplify the code.  The final result
00426  * is a (method_info *) stored the local variable @b pmth
00427  *
00428  * @b Parameters: @link #rvoid rvoid@endlink
00429  *
00430  *
00431  * @returns @link #rvoid rvoid@endlink.
00432  *
00433  */
00434 #define CALCULATE_METHOD_INFO_FROM_PC                    \
00435     clsidxmisc = GET_PC_FIELD_IMMEDIATE(thridx, clsidx); \
00436     mthidxmisc = GET_PC_FIELD_IMMEDIATE(thridx, mthidx); \
00437     pcfsmisc   = CLASS_OBJECT_LINKAGE(clsidxmisc)->pcfs; \
00438     pmth       = METHOD(clsidxmisc, mthidxmisc)
00439 
00440 
00441 /*!
00442  * @brief Calculate ClassFile pointer from a class reference.
00443  *
00444  * During the calculation, various scratch variables are
00445  * loaded and used to simplify the code.  Two final results
00446  * include a (CONSTANT_Class_info *) stored in the local variable
00447  * @b pcpd_Class stored the local variable @b pcfsmisc
00448  * and a (CONSTANT_Class_info *) stored in the local variable
00449  * @b pcpd_Class
00450  *
00451  * @param clsnameidx  constant_pool index into class file of current
00452  *                    class (as indicated in the program counter)
00453  *                    that is a class reference entry.
00454  *
00455  *
00456  * @returns @link #rvoid rvoid@endlink.
00457  *
00458  *
00459  */
00460 #define CALCULATE_CLASS_INFO_FROM_CLASS_REFERENCE(clsnameidx)          \
00461     pcpd       = pcfs->constant_pool[clsnameidx];                      \
00462     pcpd_Class = PTR_THIS_CP_Class(pcpd);                              \
00463     clsidxmisc = pcpd_Class->LOCAL_Class_binding.clsidxJVM;            \
00464     if (jvm_class_index_null == clsidxmisc)                            \
00465     {                                                                  \
00466         /* Need local variable to avoid possible expansion confusion */\
00467         jvm_constant_pool_index cpidxOLD = clsnameidx;                 \
00468                                                                        \
00469         /* If class is not loaded, go retrieve it by UTF8 class name */\
00470         LATE_CLASS_LOAD(cpidxOLD);                                     \
00471     }                                                                  \
00472     pcfsmisc = CLASS_OBJECT_LINKAGE(clsidxmisc)->pcfs; /* Extra ; */
00473 
00474 
00475 /*!
00476  * @brief Attempt to load a class that is not currently loaded.
00477  *
00478  *
00479  * @param clsnameidx  CONSTANT_Utf8_info constant_pool index
00480  *                    to class name
00481  *
00482  * @return @link #rvoid rvoid@endlink
00483  *
00484  *
00485  * @throws JVMCLASS_JAVA_LANG_NOCLASSDEFFOUNDERROR
00486  *         @link #JVMCLASS_JAVA_LANG_NOCLASSDEFFOUNDERROR
00487            if requested class cannot be located@endlink.
00488  *
00489  */
00490 #define LATE_CLASS_LOAD(clsnameidx)                                  \
00491                                                                      \
00492     pcpd       = pcfs->constant_pool[clsnameidx]; /* Class name */   \
00493     pcpd_Class = PTR_THIS_CP_Class(pcpd);                            \
00494                                                   /* UTF8 string */  \
00495     pcpd       = pcfs->constant_pool[pcpd_Class->name_index];        \
00496     pcpd_Utf8  = PTR_THIS_CP_Utf8(pcpd);                             \
00497                                                                      \
00498     prchar_clsname = utf_utf2prchar(pcpd_Utf8);                      \
00499                                                                      \
00500     /* Try again to load class */                                    \
00501     clsidxmisc = class_load_resolve_clinit(prchar_clsname,           \
00502                                            CURRENT_THREAD,           \
00503                                            rfalse,                   \
00504                                            rfalse);                  \
00505                                                                      \
00506     HEAP_FREE_DATA(prchar_clsname);                                  \
00507                                                                      \
00508     /* If class is irretrievable, abort */                           \
00509     if (jvm_class_index_null == clsidxmisc)                          \
00510     {                                                                \
00511         thread_throw_exception(thridx,                               \
00512                                THREAD_STATUS_THREW_ERROR,            \
00513                            JVMCLASS_JAVA_LANG_NOCLASSDEFFOUNDERROR); \
00514 /*NOTREACHED*/                                                       \
00515     }
00516 
00517 
00518 
00519 
00520 /*!
00521  * @brief Calculate method_info pointer from a method reference.
00522  *
00523  * During the calculation, various scratch variables are
00524  * loaded and used to simplify the code.  Two final results
00525  * include a (method_info *) stored the local variable @b pmth
00526  * and a (CONSTANT_Methodref_info *) stored in the local variable
00527  * @b pcpd_Methodref
00528  *
00529  * @param Methodref  constant_pool index into class file of current
00530  *                   class (as indicated in the program counter) that
00531  *                   is a method reference entry.
00532  *
00533  *
00534  * @returns @link #rvoid rvoid@endlink.
00535  *
00536  *
00537  * @throws JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR
00538  *         @link #JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR
00539            if requested method is not found in the class@endlink.
00540  *
00541  *
00542  */
00543 #define CALCULATE_METHOD_INFO_FROM_METHOD_REFERENCE(Methodref)         \
00544     pcpd           = pcfs->constant_pool[Methodref];                   \
00545     pcpd_Methodref = PTR_THIS_CP_Methodref(pcpd);                      \
00546     clsidxmisc     = pcpd_Methodref->LOCAL_Methodref_binding.clsidxJVM;\
00547     if (jvm_class_index_null == clsidxmisc)                            \
00548     {                                                                  \
00549         /* If class is not loaded, go retrieve it by UTF8 class name */\
00550        LATE_CLASS_LOAD(pcpd_Methodref->class_index);                   \
00551                                                                        \
00552         /* Check if method exists in loaded class */                   \
00553         clsidxmisc = pcpd_Methodref->LOCAL_Methodref_binding.clsidxJVM;\
00554         if (jvm_class_index_null == clsidxmisc)                        \
00555         {                                                              \
00556             thread_throw_exception(thridx,                             \
00557                                    THREAD_STATUS_THREW_ERROR,          \
00558                                 JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR); \
00559 /*NOTREACHED*/                                                         \
00560         }                                                              \
00561     }                                                                  \
00562                                                                        \
00563     mthidxmisc = pcpd_Methodref->LOCAL_Methodref_binding.mthidxJVM;    \
00564     if (jvm_method_index_bad == mthidxmisc)                            \
00565     {                                                                  \
00566         thread_throw_exception(thridx,                                 \
00567                                THREAD_STATUS_THREW_ERROR,              \
00568                                 JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR); \
00569 /*NOTREACHED*/                                                         \
00570     }                                                                  \
00571                                                                        \
00572     pcfsmisc       = CLASS_OBJECT_LINKAGE(clsidxmisc)->pcfs;           \
00573     pmth           = pcfsmisc->methods[mthidxmisc]
00574 
00575 
00576 /*!
00577  * @brief Check for code attribute index in local method binding.
00578  *
00579  *
00580  * @param codeatridx  Code attribute index from a local method binding
00581  *
00582  *
00583  * @return @link #rvoid rvoid@endlink
00584  *
00585  *
00586  * @throws JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR
00587  *         @link #JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR
00588       if requested class static field is not found in the class@endlink.
00589  *
00590  */
00591 #define CHECK_VALID_CODEATRIDX(codeatridx)                            \
00592     if (jvm_attribute_index_bad == codeatridx)                        \
00593     {                                                                 \
00594         thread_throw_exception(thridx,                                \
00595                                THREAD_STATUS_THREW_ERROR,             \
00596                                JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR); \
00597 /*NOTREACHED*/                                                        \
00598     }
00599 
00600 
00601 /*!
00602  * @brief Check if this method is a static method.
00603  *
00604  *
00605  * @b Parameters: @link #rvoid rvoid@endlink
00606  *
00607  *
00608  * @return @link #rvoid rvoid@endlink
00609  *
00610  *
00611  * @throws JVMCLASS_JAVA_LANG_VERIFYERROR
00612  *         @link #JVMCLASS_JAVA_LANG_VERIFYERROR
00613            if requested method is an object instance method@endlink.
00614  *
00615  */
00616 #define CHECK_STATIC_METHOD                                      \
00617                                                                  \
00618     /* Must be a static method */                                \
00619     if (!(ACC_STATIC & pmth->access_flags))                      \
00620     {                                                            \
00621         thread_throw_exception(thridx,                           \
00622                                THREAD_STATUS_THREW_ERROR,        \
00623                                JVMCLASS_JAVA_LANG_VERIFYERROR);  \
00624 /*NOTREACHED*/                                                   \
00625     }
00626 
00627 
00628 /*!
00629  * @brief Check if this method is an object instance method.
00630  *
00631  *
00632  * @b Parameters: @link #rvoid rvoid@endlink
00633  *
00634  *
00635  * @return @link #rvoid rvoid@endlink
00636  *
00637  *
00638  * @throws JVMCLASS_JAVA_LANG_VERIFYERROR
00639  *         @link #JVMCLASS_JAVA_LANG_VERIFYERROR
00640            if requested method is a static method@endlink.
00641  *
00642  */
00643 #define CHECK_INSTANCE_METHOD                                    \
00644                                                                  \
00645     /* Must be an instance method */                             \
00646     if (ACC_STATIC & pmth->access_flags)                         \
00647     {                                                            \
00648         thread_throw_exception(thridx,                           \
00649                                THREAD_STATUS_THREW_ERROR,        \
00650                                JVMCLASS_JAVA_LANG_VERIFYERROR);  \
00651 /*NOTREACHED*/                                                   \
00652     }
00653 
00654 
00655 #if 0
00656 /*!
00657  * @brief Check if this method is an @c @b abstract method,
00658  * that is, not having a concrete implementation.
00659  *
00660  *
00661  * @b Parameters: @link #rvoid rvoid@endlink
00662  *
00663  *
00664  * @return @link #rvoid rvoid@endlink
00665  *
00666  *
00667  * @throws JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
00668  *         @link #JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
00669  if requested method is a method with a concrete implementatino@endlink.
00670  *
00671  */
00672 #define CHECK_ABSTRACT_METHOD                                          \
00673                                                                        \
00674     /* Must not be a concrete method */                                \
00675     if (!(ACC_ABSTRACT & pmth->access_flags))                          \
00676     {                                                                  \
00677         thread_throw_exception(thridx,                                 \
00678                                THREAD_STATUS_THREW_ERROR,              \
00679 \
00680 /* What exception gets thrown here? Need "not" of InstantiationError */\
00681 \
00682                                JVMCLASS_JAVA_LANG_INSTANTIATIONERROR); \
00683 /*NOTREACHED*/                                                         \
00684     }
00685 #endif
00686 
00687 
00688 /*!
00689  * @brief Check if this method is a concrete method, that is,
00690  * not @c @b abstract .
00691  *
00692  *
00693  * @b Parameters: @link #rvoid rvoid@endlink
00694  *
00695  *
00696  * @return @link #rvoid rvoid@endlink
00697  *
00698  *
00699  * @throws JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
00700  *         @link #JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
00701            if requested method is an abstract method@endlink.
00702  *
00703  */
00704 #define CHECK_NOT_ABSTRACT_METHOD                                      \
00705                                                                        \
00706     /* Must not be an abstract method */                               \
00707     if (ACC_ABSTRACT & pmth->access_flags)                             \
00708     {                                                                  \
00709         thread_throw_exception(thridx,                                 \
00710                                THREAD_STATUS_THREW_ERROR,              \
00711                                JVMCLASS_JAVA_LANG_INSTANTIATIONERROR); \
00712 /*NOTREACHED*/                                                         \
00713     }
00714 
00715 
00716 /*!
00717  * @brief Check if this object is from a concrete class, that is,
00718  * not from an @c @b abstract class.
00719  *
00720  *
00721  * @b Parameters: @link #rvoid rvoid@endlink
00722  *
00723  *
00724  * @return @link #rvoid rvoid@endlink
00725  *
00726  *
00727  * @throws JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
00728  *         @link #JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
00729            if requested object is an abstract object@endlink.
00730  *
00731  */
00732 #define CHECK_NOT_ABSTRACT_CLASS                                       \
00733                                                                        \
00734     /* Must not be from an abstract class */                           \
00735     if (ACC_ABSTRACT &                                                 \
00736         OBJECT_CLASS_LINKAGE(objhashmisc)->pcfs->access_flags)         \
00737     {                                                                  \
00738         thread_throw_exception(thridx,                                 \
00739                                THREAD_STATUS_THREW_ERROR,              \
00740                                JVMCLASS_JAVA_LANG_INSTANTIATIONERROR); \
00741 /*NOTREACHED*/                                                         \
00742     }
00743 
00744 
00745 /*!
00746  * @brief Check if this object is a scalar, that is, not an array.
00747  *
00748  *
00749  * @b Parameters: @link #rvoid rvoid@endlink
00750  *
00751  *
00752  * @return @link #rvoid rvoid@endlink
00753  *
00754  *
00755  * @throws JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
00756  *         @link #JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
00757            if requested method is an array object@endlink.
00758  *
00759  */
00760 #define CHECK_NOT_ARRAY_OBJECT                                         \
00761                                                                        \
00762     /* Must not be an array object */                                  \
00763     if (OBJECT_STATUS_ARRAY &                                          \
00764         CLASS(OBJECT_CLASS_LINKAGE(objhashmisc)->clsidx).status)       \
00765     {                                                                  \
00766         thread_throw_exception(thridx,                                 \
00767                                THREAD_STATUS_THREW_ERROR,              \
00768                                JVMCLASS_JAVA_LANG_INSTANTIATIONERROR); \
00769 /*NOTREACHED*/                                                         \
00770     }
00771 
00772 
00773 /*!
00774  * @brief Check if this object is from a normal class, that is,
00775  * not from an interface class.
00776  *
00777  *
00778  * @b Parameters: @link #rvoid rvoid@endlink
00779  *
00780  *
00781  * @return @link #rvoid rvoid@endlink
00782  *
00783  *
00784  * @throws JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
00785  *         @link #JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
00786            if requested object is from an interface class@endlink.
00787  *
00788  */
00789 #define CHECK_NOT_INTERFACE_CLASS                                      \
00790                                                                        \
00791     /* Must not be from an interface class */                          \
00792     if (ACC_INTERFACE &                                                \
00793         OBJECT_CLASS_LINKAGE(objhashmisc)->pcfs->access_flags)         \
00794     {                                                                  \
00795         thread_throw_exception(thridx,                                 \
00796                                THREAD_STATUS_THREW_ERROR,              \
00797                                JVMCLASS_JAVA_LANG_INSTANTIATIONERROR); \
00798 /*NOTREACHED*/                                                         \
00799     }
00800 
00801 
00802 /*!
00803  * @brief Calculate field_info pointer from a field reference.
00804  *
00805  * During the calculation, various scratch variables are
00806  * loaded and used to simplify the code.  Two final results
00807  * include a (field_info *) stored the local variable @b pfld
00808  * and a (CONSTANT_Fieldref_info *) stored in the local variable
00809  * @b pcpd_Fieldref
00810  *
00811  * @param Fieldref  constant_pool index into class file of current
00812  *                  class (as indicated in the program counter) that
00813  *                  is a method reference entry.
00814  *
00815  *
00816  * @returns @link #rvoid rvoid@endlink.
00817  *
00818  *
00819  * @throws JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR
00820  *         @link #JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR
00821            if requested field is not found in the class@endlink.
00822  *
00823  */
00824 #define CALCULATE_FIELD_INFO_FROM_FIELD_REFERENCE(Fieldref)            \
00825     pcpd           = pcfs->constant_pool[Fieldref];                    \
00826     pcpd_Fieldref = PTR_THIS_CP_Fieldref(pcpd);                        \
00827     clsidxmisc     = pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM;  \
00828     if (jvm_class_index_null == clsidxmisc)                            \
00829     {                                                                  \
00830         /* If class is not loaded, go retrieve it by UTF8 class name */\
00831         LATE_CLASS_LOAD(pcpd_Fieldref->class_index);                   \
00832                                                                        \
00833         /* Check if field exists in loaded class */                    \
00834         clsidxmisc = pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM;  \
00835         if (jvm_class_index_null == clsidxmisc)                        \
00836         {                                                              \
00837             thread_throw_exception(thridx,                             \
00838                                    THREAD_STATUS_THREW_ERROR,          \
00839                                 JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR);  \
00840 /*NOTREACHED*/                                                         \
00841         }                                                              \
00842     }                                                                  \
00843                                                                        \
00844     fluidxmisc     = pcpd_Fieldref->LOCAL_Fieldref_binding.fluidxJVM;  \
00845     if (jvm_field_index_bad == fluidxmisc)                             \
00846     {                                                                  \
00847         thread_throw_exception(thridx,                                 \
00848                                THREAD_STATUS_THREW_ERROR,              \
00849                                 JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR);  \
00850 /*NOTREACHED*/                                                         \
00851     }                                                                  \
00852                                                                        \
00853     pcfsmisc       = CLASS_OBJECT_LINKAGE(clsidxmisc)->pcfs;           \
00854     fluidxmisc     = pcpd_Fieldref->LOCAL_Fieldref_binding.fluidxJVM;  \
00855     pfld           = pcfsmisc                                          \
00856                        ->fields[CLASS(clsidxmisc)                      \
00857                                  .class_static_field_lookup[fluidxmisc]]
00858 
00859 
00860 /*!
00861  * @brief Check for field lookup index in local field binding.
00862  *
00863  *
00864  * @param fluidx  Field lookup index from a local field binding
00865  *
00866  *
00867  * @return @link #rvoid rvoid@endlink
00868  *
00869  *
00870  * @throws JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR
00871  *         @link #JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR
00872       if requested class static field is not found in the class@endlink.
00873  *
00874  */
00875 #define CHECK_VALID_FIELDLOOKUPIDX(fluidx)                           \
00876     if (jvm_field_lookup_index_bad == fluidx)                        \
00877     {                                                                \
00878         thread_throw_exception(thridx,                               \
00879                                THREAD_STATUS_THREW_ERROR,            \
00880                                JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR); \
00881 /*NOTREACHED*/                                                       \
00882     }
00883 
00884 
00885 /*!
00886  * @brief Check if this field is a static field.
00887  *
00888  *
00889  * @b Parameters: @link #rvoid rvoid@endlink
00890  *
00891  *
00892  * @return @link #rvoid rvoid@endlink
00893  *
00894  *
00895  * @throws JVMCLASS_JAVA_LANG_INCOMPATIBLECLASSCHANGEERROR
00896  *         @link #JVMCLASS_JAVA_LANG_INCOMPATIBLECLASSCHANGEERROR
00897            if requested field is an object instance field@endlink.
00898  *
00899  */
00900 #define CHECK_STATIC_FIELD                                       \
00901                                                                  \
00902     /* Must be a static field */                                 \
00903     if (!(ACC_STATIC & pfld->access_flags))                      \
00904     {                                                            \
00905         thread_throw_exception(thridx,                           \
00906                                THREAD_STATUS_THREW_ERROR,        \
00907                JVMCLASS_JAVA_LANG_INCOMPATIBLECLASSCHANGEERROR); \
00908 /*NOTREACHED*/                                                   \
00909     }
00910 
00911 
00912 /*!
00913  * @brief Check if this field is an object instance field.
00914  *
00915  *
00916  * @b Parameters: @link #rvoid rvoid@endlink
00917  *
00918  *
00919  * @return @link #rvoid rvoid@endlink
00920  *
00921  *
00922  * @throws JVMCLASS_JAVA_LANG_INCOMPATIBLECLASSCHANGEERROR
00923  *         @link #JVMCLASS_JAVA_LANG_INCOMPATIBLECLASSCHANGEERROR
00924            if requested method is a static field@endlink.
00925  *
00926  */
00927 #define CHECK_INSTANCE_FIELD                                     \
00928                                                                  \
00929     /* Must be an instance field */                              \
00930     if (ACC_STATIC & pfld->access_flags)                         \
00931     {                                                            \
00932         thread_throw_exception(thridx,                           \
00933                                THREAD_STATUS_THREW_ERROR,        \
00934                JVMCLASS_JAVA_LANG_INCOMPATIBLECLASSCHANGEERROR); \
00935 /*NOTREACHED*/                                                   \
00936     }
00937 
00938 
00939 /*!
00940  * @brief Check if this field is a final field in the current class.
00941  *
00942  *
00943  * Determine if a final field is in the current class.  If so, fine,
00944  * but otherwise it is in a superclass.  This is an error.
00945  *
00946  * @b Parameters: @link #rvoid rvoid@endlink
00947  *
00948  *
00949  * @return @link #rvoid rvoid@endlink
00950  *
00951  *
00952  * @throws JVMCLASS_JAVA_LANG_ILLEGALACCESSERROR
00953  *         @link #JVMCLASS_JAVA_LANG_ILLEGALACCESSERROR
00954            if requested field is final, but in a superclass@endlink.
00955  *
00956  */
00957 #define CHECK_FINAL_FIELD_CURRENT_CLASS                          \
00958                                                                  \
00959     {                                                            \
00960         jvm_class_index clsidxTMP;                               \
00961                                                                  \
00962         GET_PC_FIELD(thridx, clsidxTMP, clsidx);                 \
00963                                                                  \
00964         /* A final field must _not_ be found in a superclass */  \
00965         if ((ACC_FINAL & pfld->access_flags) &&                  \
00966             (clsidxTMP != pcpd_Fieldref                          \
00967                             ->LOCAL_Fieldref_binding.clsidxJVM)) \
00968         {                                                        \
00969             thread_throw_exception(thridx,                       \
00970                                    THREAD_STATUS_THREW_ERROR,    \
00971                        JVMCLASS_JAVA_LANG_ILLEGALACCESSERROR);   \
00972 /*NOTREACHED*/                                                   \
00973         }                                                        \
00974     }
00975 
00976 
00977 /*!
00978  * @brief Check if this field requires two @link #jint jint@endlink
00979  * accesses or just one.
00980  *
00981  *
00982  * JVM stack operations and local variable accesses need to know
00983  * if the datum to be moved takes one @link #jint jint@endlink slot
00984  * or two.  Items of types @link #jlong jlong@endlink and
00985  * @link #jdouble jdouble@endlink take two such accesses, all others
00986  * take just one.
00987  *
00988  * @b Parameters: @link #rvoid rvoid@endlink
00989  *
00990  *
00991  * @returns @link #rtrue rtrue@endlink if this field takes two
00992  * accesses, otherwise @link #rfalse rfalse@endlink for smaller types.
00993  *
00994  */
00995 #define CHECK_TWO_ACCESSES                                         \
00996                                                                    \
00997     (((pcpd_Fieldref->LOCAL_Fieldref_binding.jvaluetypeJVM ==      \
00998        BASETYPE_CHAR_J)                                         || \
00999       (pcpd_Fieldref->LOCAL_Fieldref_binding.jvaluetypeJVM ==      \
01000        BASETYPE_CHAR_D))                                           \
01001     ? rtrue                                                        \
01002     : rfalse)
01003 
01004 
01005 /*!
01006  * @brief Store out value by data type into either class static field
01007  * or object instance field.
01008  *
01009  *
01010  * @param data_array  Expression pointing to the class' or object's
01011  *                    @b XXX_data[] array, namely a (jvalue *).
01012  *                    Typically a fixed set of two expressions.
01013  *
01014  *
01015  * @returns @link #rvoid rvoid@endlink
01016  *
01017  *
01018  * @see PUTFIELD
01019  *
01020  * @see PUTSTATIC
01021  *
01022  *
01023  * @todo The various type casting games of integer/sub-integer
01024  *       and integer/float/double and integer/objhash need to be
01025  *       carefully scrutinized for correctness at run time.
01026  *
01027  * @todo Is BASTYPE_CHAR_ARRAY a legal case for @b PUTSTATIC and
01028  *       @b PUTFIELD ?
01029  *
01030  */
01031 #define PUTDATA(data_array)                                            \
01032     switch (pcpd_Fieldref->LOCAL_Fieldref_binding.jvaluetypeJVM)       \
01033     {                                                                  \
01034         case BASETYPE_CHAR_B:                                          \
01035             POP(thridx,                                                \
01036                 data_array._jbyte,                                     \
01037                 jbyte);                                                \
01038             break;                                                     \
01039                                                                        \
01040         case BASETYPE_CHAR_C:                                          \
01041             POP(thridx,                                                \
01042                 data_array._jchar,                                     \
01043                 jchar);                                                \
01044             break;                                                     \
01045                                                                        \
01046         case BASETYPE_CHAR_D:                                          \
01047             /*                                                         \
01048              * DO NOT pop into a 64-bit word!  @link #POP() POP@endlink\
01049              * was only designed to operate on 32-bit data types.      \
01050              * Instead, use two instances.  Besides, these halves      \
01051              * needs to get pushed through bytegames_combine_jdouble() \
01052              * anyway to retrieve the final                            \
01053              * @link #jdouble jdouble@endlink value.                   \
01054              */                                                        \
01055             POP(thridx, jitmp2, jint);                                 \
01056             POP(thridx, jitmp1, jint);                                 \
01057             data_array._jdouble = bytegames_combine_jdouble(jitmp1,    \
01058                                                             jitmp2);   \
01059             break;                                                     \
01060                                                                        \
01061         case BASETYPE_CHAR_F:                                          \
01062             /*                                                         \
01063              * DO NOT pop into a jfloat!  This will consider           \
01064              * the source as an integer to be converted instead        \
01065              * of a 32-bit floating point word stored in a 32-bit      \
01066              * integer word on the stack.  Instead, use the            \
01067              * FORCE_JFLOAT() macro to sustain contents across         \
01068              * type boundaries.                                        \
01069              */                                                        \
01070             POP(thridx, jitmp1, jint);                                 \
01071             data_array._jfloat = FORCE_JFLOAT(jitmp1);                 \
01072             break;                                                     \
01073                                                                        \
01074         case BASETYPE_CHAR_I:                                          \
01075             POP(thridx,                                                \
01076                 data_array._jint,                                      \
01077                 /* redundant: */ jint);                                \
01078             break;                                                     \
01079                                                                        \
01080         case BASETYPE_CHAR_J:                                          \
01081             /*                                                         \
01082              * DO NOT pop into a 64-bit word!  @link #POP() POP@endlink\
01083              * was only designed to operate on 32-bit data types.      \
01084              * Instead, use two instances.  Besides, these halves      \
01085              * needs to get pushed through bytegames_combine_jlong()   \
01086              * anyway to retrieve the final                            \
01087              * @link #jlong jlong@endlink value.                       \
01088              */                                                        \
01089             POP(thridx, jitmp2, jint);                                 \
01090             POP(thridx, jitmp1, jint);                                 \
01091             jltmp = bytegames_combine_jlong(jitmp1, jitmp2);           \
01092             data_array._jlong = jltmp;                                 \
01093             break;                                                     \
01094                                                                        \
01095         case BASETYPE_CHAR_L:                                          \
01096             POP(thridx,                                                \
01097                 data_array._jobjhash,                                  \
01098                 jvm_object_hash);                                      \
01099             break;                                                     \
01100                                                                        \
01101         case BASETYPE_CHAR_S:                                          \
01102             POP(thridx,                                                \
01103                 data_array._jshort,                                    \
01104                 jshort);                                               \
01105             break;                                                     \
01106                                                                        \
01107         case BASETYPE_CHAR_Z:                                          \
01108             POP(thridx,                                                \
01109                 data_array._jboolean,                                  \
01110                 jboolean);                                             \
01111             break;                                                     \
01112                                                                        \
01113         case BASETYPE_CHAR_ARRAY:                                      \
01114             POP(thridx,                                                \
01115                 data_array._jarray,                                    \
01116                 jvm_object_hash);                                      \
01117             break;                                                     \
01118                                                                        \
01119         case LOCAL_BASETYPE_ERROR:                                     \
01120         default:                                                       \
01121             /* Something is @e very wrong if code gets here */         \
01122             thread_throw_exception(thridx,                             \
01123                                    THREAD_STATUS_THREW_ERROR,          \
01124                                    JVMCLASS_JAVA_LANG_VERIFYERROR);    \
01125 /*NOTREACHED*/                                                         \
01126             break;                                                     \
01127     }
01128 
01129 
01130 /*!
01131  * @brief Store out value by data type into class static field.
01132  *
01133  */
01134 #define PUTSTATIC                                                  \
01135     PUTDATA(CLASS(pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM) \
01136               .class_static_field_data[fluidxmisc])
01137 
01138 
01139 /*!
01140  * @brief Store out value by data type into object instance field.
01141  *
01142  */
01143 #define PUTFIELD                                                     \
01144      PUTDATA(OBJECT(pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM) \
01145                .object_instance_field_data[fluidxmisc])
01146 
01147 
01148 /*!
01149  * @brief Retrieve value by data type from either class static field or
01150  * object instance field.
01151  *
01152  *
01153  * @param data_array  Expression pointing to the class' or object's
01154  *                    @b XXX_data[] array, namely a (jvalue *).
01155  *                    Typically a fixed set of two expressions.
01156  *
01157  *
01158  * @returns @link #rvoid rvoid@endlink
01159  *
01160  *
01161  * @see GETFIELD
01162  *
01163  * @see GETSTATIC
01164  *
01165  *
01166  * @todo The various type casting games of integer/sub-integer
01167  *       and integer/float/double and integer/objhash need to be
01168  *       carefully scrutinized for correctness at run time.
01169  *
01170  * @todo Is BASTYPE_CHAR_ARRAY a legal case for @b GETSTATIC and
01171  *       @b GETFIELD ?
01172  *
01173  */
01174 #define GETDATA(data_array)                                            \
01175     switch (pcpd_Fieldref->LOCAL_Fieldref_binding.jvaluetypeJVM)       \
01176     {                                                                  \
01177         case BASETYPE_CHAR_B:                                          \
01178             PUSH(thridx,                                               \
01179                  (jint) data_array._jbyte);                            \
01180             break;                                                     \
01181                                                                        \
01182         case BASETYPE_CHAR_C:                                          \
01183             PUSH(thridx,                                               \
01184                 (jint) data_array._jchar);                             \
01185             break;                                                     \
01186                                                                        \
01187         case BASETYPE_CHAR_D:                                          \
01188             bytegames_split_jdouble(data_array._jdouble,               \
01189                                     &jitmp1,                           \
01190                                     &jitmp2);                          \
01191             /*                                                         \
01192              * DO NOT push from a 64-bit word! @link #PUSH()           \
01193                PUSH@endlink was only designed to operate on 32-bit     \
01194              * data types.  Instead, use two instances.                \
01195              */                                                        \
01196             PUSH(thridx, jitmp1);                                      \
01197             PUSH(thridx, jitmp2);                                      \
01198             break;                                                     \
01199                                                                        \
01200         case BASETYPE_CHAR_F:                                          \
01201             /*                                                         \
01202              * DO NOT pop into a jfloat!  This will consider           \
01203              * the source as an integer to be converted instead        \
01204              * of a 32-bit floating point word stored in a 32-bit      \
01205              * integer word on the stack.  Instead, use the            \
01206              * FORCE_JFLOAT() macro to sustain contents across         \
01207              * type boundaries.                                        \
01208              */                                                        \
01209             jitmp1 = FORCE_JINT(data_array._jfloat);                   \
01210             PUSH(thridx, jitmp1);                                      \
01211             break;                                                     \
01212                                                                        \
01213         case BASETYPE_CHAR_I:                                          \
01214             PUSH(thridx,                                               \
01215                  (jint) /* ... redundant */ data_array._jint);         \
01216             break;                                                     \
01217                                                                        \
01218         case BASETYPE_CHAR_J:                                          \
01219             bytegames_split_jlong(data_array._jlong,                   \
01220                                   &jitmp1,                             \
01221                                   &jitmp2);                            \
01222             /*                                                         \
01223              * DO NOT push from a 64-bit word! @link #PUSH()           \
01224                PUSH@endlink was only designed to operate on 32-bit     \
01225              * data types.  Instead, use two instances.                \
01226              */                                                        \
01227             PUSH(thridx, jitmp1);                                      \
01228             PUSH(thridx, jitmp2);                                      \
01229             break;                                                     \
01230                                                                        \
01231         case BASETYPE_CHAR_L:                                          \
01232             PUSH(thridx,                                               \
01233                  (jint) data_array._jobjhash);                         \
01234             break;                                                     \
01235                                                                        \
01236         case BASETYPE_CHAR_S:                                          \
01237             PUSH(thridx,                                               \
01238                  (jint) data_array._jshort);                           \
01239             break;                                                     \
01240                                                                        \
01241         case BASETYPE_CHAR_Z:                                          \
01242             PUSH(thridx,                                               \
01243                  (jint) data_array._jboolean);                         \
01244             break;                                                     \
01245                                                                        \
01246         case BASETYPE_CHAR_ARRAY:                                      \
01247             PUSH(thridx,                                               \
01248                  (jint) data_array._jarray);                           \
01249             break;                                                     \
01250                                                                        \
01251         case LOCAL_BASETYPE_ERROR:                                     \
01252         default:                                                       \
01253             /* Something is @e very wrong if code gets here */         \
01254             thread_throw_exception(thridx,                             \
01255                                    THREAD_STATUS_THREW_ERROR,          \
01256                                    JVMCLASS_JAVA_LANG_VERIFYERROR);    \
01257 /*NOTREACHED*/                                                         \
01258             break;                                                     \
01259     }
01260 
01261 
01262 /*!
01263  * @brief Retrieve value by data type from class static field.
01264  *
01265  */
01266 #define GETSTATIC                                                  \
01267     GETDATA(CLASS(pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM) \
01268               .class_static_field_data[fluidxmisc])
01269 
01270 
01271 /*!
01272  * @brief Retrieve value by data type from object instance field.
01273  *
01274  */
01275 #define GETFIELD                                                    \
01276     GETDATA(OBJECT(pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM) \
01277               .object_instance_field_data[fluidxmisc])
01278 
01279 
01280 /*@} */ /* End of grouped definitions */
01281 
01282 /*!
01283  * Handler linkage for end of thread detection.
01284  */
01285 static jmp_buf opcode_end_thread_return;
01286 
01287 
01288 /*!
01289  * @brief JVM inner loop setup for end of thread detection-- implements
01290  * @c @b setjmp(3) .
01291  *
01292  *
01293  * Use this function to arm handler for non-local exit from the
01294  * inner @c @b while() loop when a thread has finished
01295  * running.
01296  *
01297  * @b Parameters: @link #rvoid rvoid@endlink
01298  *
01299  *
01300  * @returns From normal setup, integer
01301  *          @link #EXIT_MAIN_OKAY EXIT_MAIN_OKAY@endlink.
01302  *          Otherwise, return
01303  *          @link #exit_code_enum exit_enum code enumeration@endlink
01304  *          from @link #opcode_end_thread_test()
01305             opcode_end_thread_test()@endlink.
01306  *
01307  */
01308 
01309 static int opcode_end_thread_setup(rvoid)
01310 {
01311     /*
01312      * Return point from @c @b longjmp(3) as declared
01313      * in @link #opcode_end_thread_test()
01314        opcode_end_thread_test()@endlink
01315      */
01316     return(setjmp(opcode_end_thread_return));
01317 
01318 } /* END of opcode_end_thread_setup() */
01319 
01320 
01321 /*!
01322  * @brief Detect end of thread when stack frame is empty at
01323  * @b return time and perform non-local return-- implements
01324  * @c @b longjmp(3) .
01325  *
01326  * Use this function to test for end of thread execution and to
01327  * perform a non-local return from the inner @c @b while()
01328  * loop when a thread has finished running.
01329  *
01330  * This function is invoked from within each of the Java
01331  * @b return family of opcodes to detect if the stack frame is
01332  * empty after a @link #POP_FRAME() POP_FRAME()@endlink.  If this
01333  * test passes, then the stack frame is empty and the thread has
01334  * nothing else to do.  It is therefore moved into the @b COMPLETE
01335  * state and a non-local return exits the while loop.
01336  *
01337  *
01338  * @param thridx  Thread index of thread to evaluate.
01339  *
01340  *
01341  * @returns @link #rvoid rvoid@endlink if end of thread test fails.
01342  *          If test passes, perform non-local state restoration from
01343  *          setup via @c @b setjmp(3) as stored in @link
01344             #opcode_end_thread_return opcode_end_thread_return@endlink.
01345  *
01346  */
01347 
01348 static rvoid opcode_end_thread_test(jvm_thread_index thridx)
01349 {
01350     /* Check if thread has finished running */
01351 
01352     /*!
01353      * Check both current end of program FP and final FP in case
01354      * something like a @c @b <clinit> or @c @b <init> was loaded
01355      * on top of a running program.
01356      *
01357      * @todo Should FP condition be fp_end_program <= THREAD().fp
01358      *       instead of < condition? 
01359      *
01360      */
01361     if (THREAD(thridx).fp_end_program < THREAD(thridx).fp)
01362     {
01363         /* Thread is still running something, so continue */
01364         return;
01365     }
01366 
01367     /* Thread has finished running, so return to @c @b setjmp(3) */
01368 
01369     int rc = (int) EXIT_JVM_THREAD;
01370     longjmp(opcode_end_thread_return, rc);
01371 /*NOTREACHED*/
01372 
01373 } /* END of opcode_end_thread_test() */
01374 
01375 
01376 /*!
01377  * @brief Double-fault error state variable for throwable event.
01378  *
01379  * This boolean reports the the error-within-an-error state condition
01380  * within
01381  * @link #rvoid opcode_load_run_throwable()
01382    opcode_load_run_throwable()@endlink
01383  */
01384 rboolean opcode_calling_java_lang_linkageerror =
01385     CHEAT_AND_USE_FALSE_TO_INITIALIZE;
01386 
01387 
01388 /*!
01389  * @brief Load a @c @b java.lang.Throwable event, typically
01390  * an @b Error or @b Exception and run its @c @b <clinit> method
01391  * followed by its @c @b <init> method with default parameters.
01392  *
01393  * This function must @e not be called until
01394  * @c @b java.lang.Object , @c @b java.lang.Class,
01395  * @c @b java.lang.String , @c @b java.lang.Throwable
01396  * @c @b java.lang.Error have been loaded and initialized.
01397  *
01398  * There is @e no attempt to enforce which classes may be invoked
01399  * by this handler.  It is assumed that the caller will @e only
01400  * pass in subclasses of
01401  * @link #JVMCLASS_JAVA_LANG_ERROR JVMCLASS_JAVA_LANG_ERROR@endlink.
01402  * Anything else will produce undefined results.
01403  *
01404  * @warning <b>This handler is not a simple as it seems!</b>  You
01405  * absolutely @e must know what the non-local return mechanism
01406  * @c @b setjmp(3)/longjmp(3) is before attempting to figure it out!!!
01407  *
01408  * The strategy is a simple one:  Trap thrown errors by this handler
01409  * and trap a failure in that error class by throwing a @link
01410    #JVMCLASS_JAVA_LANG_INTERNALERROR
01411    JVMCLASS_JAVA_LANG_INTERNALERROR@endlink.  If that fails, give up.
01412  *
01413  * @b Details:  When this function is first called due to a thrown
01414  * error, it attempts to load and run that error class.  If all
01415  * is well, that class runs and everyone lives happily ever after.
01416  * If that class throws an error, however, this handler, having
01417  * been re-armed, is activated semi-recursively via @link
01418    #exit_throw_exception() exit_throw_exception()@endlink,
01419  * (that is, not entering at the top of function, but at the return
01420  * from @link #exit_throw_exception() exit_throw_exception()@endlink
01421  * with a non-zero return value), entering @e this code at
01422  * @link #exit_exception_setup exit_exception_setup()@endlink,
01423  * choosing the conditional branch != @link #EXIT_MAIN_OKAY
01424    EXIT_MAIN_OKAY@endlink and attempts to recursively load and
01425  * run @link #JVMCLASS_JAVA_LANG_LINKAGEERROR
01426    JVMCLASS_JAVA_LANG_LINKAGEERROR@endlink.  If this is successful,
01427  * fine, call @link #exit_jvm() exit_jvm()@endlink and be done.
01428  * However, if even @e this fails and throws an error, the handler,
01429  * having been rearmed @e again by the attempt to invoke
01430  * @link #JVMCLASS_JAVA_LANG_LINKAGEERROR
01431    JVMCLASS_JAVA_LANG_LINKAGEERROR@endlink, it again semi-recursively
01432  * is activated via @link #exit_throw_exception()
01433    exit_throw_exception()@endlink and again enters the code at
01434  * @link #exit_exception_setup() exit_exception_setup()@endlink.  This
01435  * time, the global
01436  * @link #opcode_calling_java_lang_linkageerror
01437    opcode_calling_java_lang_linkageerror@endlink is
01438  * @link #rtrue rtrue@endlink, so no more recursive invocations
01439  * are performed.  Instead, @link #exit_jvm() exit_jvm()@endlink
01440  * with the most recent @link #EXIT_MAIN_OKAY EXIT_xxx@endlink code
01441  * from @link #exit_throw_exception() exit_throw_exception()@endlink
01442  * and be done.
01443  *
01444  *
01445  * @param  pThrowableEvent  Null-terminated string name of
01446  *                          throwable class.
01447  *
01448  * @param  thridx           Thread table index of thread to load this
01449  *                          @c @b java.lang.Throwable sub-class
01450  *                          into.
01451  *
01452  *
01453  * @returns  @link #rvoid rvoid@endlink.  Either the
01454  *           @c @b java.lang.Throwable class loads and
01455  *           runs, or it loads @c @b java.lang.LinkageError
01456  *           and runs it, then returns to caller, or it exits
01457  *           due to an error somewhere in this sequence of
01458  *           events.
01459  *
01460  */
01461 
01462 rvoid opcode_load_run_throwable(rchar            *pThrowableEvent,
01463                                 jvm_thread_index  thridx)
01464 {
01465     /******* Re-arm java.lang.LinkageError handler ***/
01466 
01467 
01468     /*!
01469      * @internal This call to exit_exception_setup() and the following
01470      * if (@link #EXIT_MAIN_OKAY EXIT_MAIN_OKAY@endlink) statement
01471      * constitute the ugly part of this code as described above.
01472      * See also other recursive calls and their control via
01473      * @link #opcode_calling_java_lang_linkageerror
01474        opcode_calling_java_lang_linkageerror@endlink:
01475      *
01476      */
01477     int nonlocal_rc = exit_exception_setup();
01478 
01479     if (EXIT_MAIN_OKAY != nonlocal_rc)
01480     {
01481         /*!
01482          * @todo  Make this load and run the error class
01483          *        @c @b <clinit> and default @c @b <init> method
01484          *        instead of/in addition to fprintf().  Other
01485          *        exit_throw_exception() handlers will have invoked
01486          *        this method, so it @e must be rearmed @e again at
01487          *        this point, lest an error that invokes it causes
01488          *        an infinite loop.
01489          */
01490 
01491         /* Should never be true via exit_throw_exception() */
01492         if (rnull == exit_LinkageError_subclass)
01493         {
01494             exit_LinkageError_subclass = "unknown";
01495         }
01496 
01497         fprintfLocalStderr(
01498             "opcode_load_run_throwable:  Recursive Error %d (%s): %s\n",
01499             nonlocal_rc,
01500             exit_get_name(nonlocal_rc),
01501             exit_LinkageError_subclass);
01502 
01503         jvmutil_print_stack(thridx, (rchar *) rnull);
01504 
01505         /*
01506          * WARNING!!! Recursive call, but will only go 1 level deep.
01507          */
01508         if (rfalse == opcode_calling_java_lang_linkageerror)
01509         {
01510             opcode_calling_java_lang_linkageerror = rtrue;
01511 
01512             opcode_load_run_throwable(JVMCLASS_JAVA_LANG_LINKAGEERROR,
01513                                       rtrue);
01514 
01515             opcode_calling_java_lang_linkageerror = rfalse;
01516         }
01517 
01518         exit_jvm(nonlocal_rc);
01519 /*NOTREACHED*/
01520     }
01521 
01522     if (jvm_thread_index_null == thridx)
01523     {
01524         sysErrMsg("opcode_load_run_throwable",
01525              "Invalid thread index %d for throwable class %s",
01526                 thridx, pThrowableEvent);
01527         return;
01528     }
01529 
01530     /*!
01531      * @internal Load error class and run its @c @b <clinit> method.
01532      *
01533      * If an error is thrown by class_load_resolve_clinit(),
01534      * re-enter this error function recursively at
01535      * exit_exception_setup().
01536      */
01537     jvm_class_index clsidx =
01538         class_load_resolve_clinit(pThrowableEvent,
01539                                   thridx,
01540                                   rfalse, /* N/A due to valid thridx */
01541                                   rfalse);
01542 
01543     /*!
01544      * @internal Both mark (here) and unmark (below) class
01545      * so it gets garbage collected.
01546      */
01547     (rvoid) GC_CLASS_MKREF_FROM_CLASS(jvm_class_index_null, clsidx);
01548 
01549 
01550     /*!
01551      * @internal Instantiate error class object and run its default
01552      * @c @b <init> method with default parameters.
01553      *
01554      * If an error is thrown in objec_instance_new(), re-enter this
01555      * error function recursively at exit_exception_setup().
01556      */
01557     jvm_object_hash objhash=
01558         object_instance_new(THREAD_STATUS_EMPTY,
01559                             CLASS_OBJECT_LINKAGE(clsidx)->pcfs,
01560                             clsidx,
01561                             LOCAL_CONSTANT_NO_ARRAY_DIMS,
01562                             (jint *) rnull,
01563                             rtrue,
01564                             thridx);
01565 
01566     /*!
01567      * @internal Both mark and unmark object so it
01568      * gets garbage collected
01569      */
01570     (rvoid) GC_OBJECT_MKREF_FROM_OBJECT(jvm_object_hash_null, objhash);
01571     (rvoid) GC_OBJECT_RMREF_FROM_OBJECT(jvm_object_hash_null, objhash);
01572 
01573     /*!
01574      * @internal Unmarked from above-- since JVM is going down,
01575      * this may be irrelevant, but be consistent.
01576      */
01577     (rvoid) GC_CLASS_RMREF_FROM_CLASS(jvm_class_index_null, clsidx);
01578 
01579     return;
01580 
01581 } /* END of opcode_load_run_throwable() */
01582 
01583 
01584 /*!
01585  * @brief Inner loop of JVM virtual instruction execution engine.
01586  *
01587  * Only run the inner loop until:
01588  *
01589  * <ul>
01590  * <li> thread state changes </li>
01591  * <li> time slice expired </li>
01592  * <li> thread completes (when FP is not 0, that is,
01593  *      not @link #JVMCFG_NULL_SP JVMCFG_NULL_SP@endlink) </li>
01594  * </ul>
01595  *
01596  * Any remaining time on this time slice will go against
01597  * the next thread, which may only have a small amount
01598  * of time, even none at all.  This is a natural effect
01599  * of any time-slicing algorithm.
01600  *
01601  * Logic similar to the uncaught exception handler of this function
01602  * may be found in object_run_method() as far as initiating execution
01603  * of a JVM method.
01604  *
01605  * @todo  See if there is a better time-slicing algorithm that
01606  *        is just as easy to use and keeps good real clock time.
01607  * 
01608  * @todo:  having @c @b run_init_ (parm 7) for invocations of
01609  *         opject_instance_new() to be @link #rfalse rfalse@endlink
01610  *         the right thing to do for array initialization, namely
01611  *         opcodes @b NEWARRAY and @b ANEWARRAY ?  Initializing an
01612  *         array is really not a constructor type
01613  *         of operation, but the individual components
01614  *         (elements) of the array probably would be,
01615  *         and with default parameters.
01616  *
01617  *
01618  *
01619  * @param  thridx            Thread index of thread to run
01620  *
01621  * @param  check_timeslice   @link #rtrue rtrue@endlink if JVM time
01622  *                           slice preempts execution after maximum
01623  *                           time exceeded.
01624  *
01625  *
01626  * @returns @link #rtrue rtrue@endlink if this method and/or time slice
01627  *          ran correctly (whether or not the thread finished running),
01628  *          or @link #rfalse rfalse@endlink if an
01629  *          uncaught exception was thrown or if an
01630  *          Error, Exception, or Throwable was thrown, or if a
01631  *          thread state could not be properly changed.
01632  *
01633  */
01634 rboolean opcode_run(jvm_thread_index thridx,
01635                     rboolean check_timeslice)
01636 {
01637     /*
01638      * Arm handler for the three conditions
01639      * java.lang.Error, Exception, and Throwable.
01640      *
01641      * Any JVM virtual execution that throws one of
01642      * these that is @e not covered by an exception
01643      * handler in the class will issue:
01644      *
01645      *     <b><code>
01646            longjmp(THREAD(thridx).nonlocal_ThrowableEvent, rc)
01647            </b></code>
01648      *
01649      * by way of @link #thread_throw_exception() 
01650        thread_throw_exception@endlink, which will return to the
01651      * @c @b else branch of this @c @b if .  It will
01652      * contain a @link rthread#status (rthread.status@endlink bit
01653      * @b THREAD_STATUS_xxx which may be examined there.  Notice that
01654      * @c @b int is wider than @c @b rushort and thus
01655      * will not lose any information in the implicit conversion.
01656      */
01657 
01658     /* Inner loop end of thread detection, init to unused value */
01659     int nonlocal_thread_return = EXIT_JVM_INTERNAL;
01660 
01661     /* Calls @c @b setjmp(3) to arm handler */
01662     int nonlocal_rc = thread_exception_setup(thridx);
01663 
01664     /* Show error case first due to @e long switch() following */
01665     if (THREAD_STATUS_EMPTY != nonlocal_rc)
01666     {
01667         /*
01668          * Examine only the @c @b longjmp(3) conditions (should be
01669          * irrelevant due to filter in @link #thread_throw_exception()
01670            thread_throw_exception()@endlink
01671          */
01672         nonlocal_rc &= (THREAD_STATUS_THREW_EXCEPTION |
01673                         THREAD_STATUS_THREW_ERROR |
01674                         THREAD_STATUS_THREW_THROWABLE |
01675                         THREAD_STATUS_THREW_UNCAUGHT);
01676 
01677         /*
01678          * Local copy of @link rthread#pThrowable pThrowable@endlink
01679          * for use below
01680          */
01681         rchar *pThrowableEvent = THREAD(thridx).pThrowableEvent;
01682 
01683         /*
01684          * Clear out the Throwable condition now that it
01685          * is being processed, in case of multiple exceptions.
01686          */
01687         THREAD(thridx).pThrowableEvent = (rchar *) rnull;
01688         THREAD(thridx).status &= ~(THREAD_STATUS_THREW_EXCEPTION |
01689                                    THREAD_STATUS_THREW_ERROR |
01690                                    THREAD_STATUS_THREW_THROWABLE |
01691                                    THREAD_STATUS_THREW_UNCAUGHT);
01692 
01693         /*
01694          * Process the specifics for each java.lang.Throwable
01695          * condition before doing the generic processing.
01696          */
01697         if (THREAD_STATUS_THREW_EXCEPTION & nonlocal_rc)
01698         {
01699             /*! @todo  What needs to go here? */
01700         }
01701         else
01702         if (THREAD_STATUS_THREW_ERROR & nonlocal_rc)
01703         {
01704             /*! @todo  What needs to go here? */
01705         }
01706         else
01707         if (THREAD_STATUS_THREW_THROWABLE & nonlocal_rc)
01708         {
01709             /*! @todo  What needs to go here? */
01710         }
01711         else
01712         if (THREAD_STATUS_THREW_UNCAUGHT & nonlocal_rc)
01713         {
01714             /*
01715              * Handle an uncaught exception.  @b pThrowableEvent will
01716              * be @link #rnull rnull@endlink here, so there is nothing
01717              * to get from it.
01718              */
01719 
01720             jvm_class_index clsidx = class_find_by_prchar(
01721                                         JVMCLASS_JAVA_LANG_THREADGROUP);
01722 
01723             if (jvm_class_index_null == clsidx)
01724             {
01725                 /* Problem creating error class, so quit */
01726                 sysErrMsg("opcode_run",
01727                      "Cannot find class %s",
01728                      JVMCLASS_JAVA_LANG_THREADGROUP);
01729 
01730                 jvmutil_print_stack(thridx, (rchar *) rnull);
01731 
01732                 exit_jvm(EXIT_JVM_CLASS);
01733 /*NOTREACHED*/
01734             }
01735 
01736             /*!
01737              * @todo Get @c @b ThreadGroup logic working that
01738              * figures out which @c @b java.lang.ThreadGroup
01739              * this thread is a part of and invoke
01740              * @c @b java.lang.ThreadGroup.uncaughtException()
01741              * for that specific object instead of this general method.
01742              * Probably the class library will gripe about not knowing
01743              * which object to associate with the method call since
01744              * @c @b java.lang.ThreadGroup.uncaughtException()
01745              * is @e not a @c @b static method.
01746              */
01747 
01748             /*
01749              * Set FP lower boundary so Java @c @b return
01750              * instruction does not keep going after handler, check if
01751              * @c @b java.lang.ThreadGroup.uncaughtException()
01752              * is there, and run it.
01753              */
01754             jvm_sp fp_save_end_program = THREAD(thridx).fp_end_program;
01755 
01756             /*
01757              * Make JVM stop once
01758              * @c @b java.lang.ThreadGroup.uncaughtException()
01759              * is done
01760              */
01761             THREAD(thridx).fp_end_program = THREAD(thridx).fp;
01762 
01763             /* Continue getting pieces for PUT_PC_IMMEDIATE() */
01764             jvm_method_index mthidx =
01765                 method_find_by_prchar(clsidx,
01766                                       JVMCFG_UNCAUGHT_EXCEPTION_METHOD,
01767                                       JVMCFG_UNCAUGHT_EXCEPTION_PARMS);
01768 
01769             if (jvm_method_index_bad == mthidx)
01770             {
01771                 exit_throw_exception(EXIT_JVM_METHOD,
01772                                   JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
01773 /*NOTREACHED*/
01774             }
01775 
01776             /*
01777              * Load up entry point for Throwable call
01778              */
01779             ClassFile *pcfs = CLASS_OBJECT_LINKAGE(clsidx)->pcfs;
01780 
01781             jvm_attribute_index codeatridx =
01782                 pcfs->methods[mthidx]
01783                         ->LOCAL_method_binding.codeatridxJVM;
01784 
01785             if (jvm_attribute_index_bad == codeatridx)
01786             {
01787                 exit_throw_exception(EXIT_JVM_ATTRIBUTE,
01788                                   JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
01789 /*NOTREACHED*/
01790             }
01791 
01792             if (jvm_attribute_index_native == codeatridx)
01793             {
01794                 /* Pass parameters for both local method and JNI call */
01795                 native_run_method(thridx,
01796                                   pcfs
01797                                     ->methods[mthidx]
01798                                       ->LOCAL_method_binding.nmordJVM,
01799                                   clsidx,
01800                                   pcfs->methods[mthidx]->name_index,
01801                                   pcfs->methods[mthidx]
01802                                     ->descriptor_index);
01803             }
01804             else
01805             {
01806                 Code_attribute *pca = (Code_attribute *)
01807                          &pcfs->methods[mthidx]->attributes[codeatridx];
01808                 PUSH_FRAME(thridx, pca->max_locals);
01809                 PUT_PC_IMMEDIATE(thridx,
01810                                  clsidx,
01811                                  mthidx,
01812                                  pcfs
01813                                    ->methods[mthidx]
01814                                    ->LOCAL_method_binding.codeatridxJVM,
01815                                  pcfs
01816                                    ->methods[mthidx]
01817                                    ->LOCAL_method_binding.excpatridxJVM,
01818                                  CODE_CONSTRAINT_START_PC);
01819 
01820                 if (rfalse == opcode_run(thridx, rfalse))
01821                 {
01822                     /* Problem running error class, so quit */
01823                     sysErrMsg("opcode_run",
01824                               "Cannot run exception method %s %s%s",
01825                               JVMCLASS_JAVA_LANG_THREADGROUP,
01826                               JVMCFG_UNCAUGHT_EXCEPTION_METHOD,
01827                               JVMCFG_UNCAUGHT_EXCEPTION_PARMS);
01828 
01829                     jvmutil_print_stack(thridx, (rchar *) rnull);
01830 
01831                     exit_jvm(EXIT_JVM_THREAD);
01832 /*NOTREACHED*/
01833                 }
01834             }
01835 
01836             /*
01837              * This would normally permit java.lang.Exception 
01838              * and java.lang.Throwable to continue by restoring
01839              * lower FP boundary, but unwind here anyway for
01840              * proper frame contents for later diagnostics.
01841              */
01842             THREAD(thridx).fp_end_program = fp_save_end_program;
01843 
01844             /* Attempt to shut down thread due to condition */
01845             if (rfalse == threadstate_request_complete(thridx))
01846             {
01847                 sysErrMsg("opcode_run",
01848                  "Unable to move completed thread %d to '%s' state",
01849                           thridx,
01850                           thread_state_get_name(THREAD_STATE_COMPLETE));
01851                 THREAD_REQUEST_NEXT_STATE(badlogic, thridx);
01852 
01853                 return(rfalse);
01854             }
01855 
01856             return(rfalse);
01857 
01858         } /* if THREAD_STATUS_THREW_UNCAUGHT */
01859         else
01860         {
01861             /*! @todo  What needs to go here, if anything? */
01862         }
01863 
01864         /* Completely handled THREAD_STATUS_THREW_UNCAUGHT above */
01865         if (nonlocal_rc & (THREAD_STATUS_THREW_EXCEPTION |
01866                            THREAD_STATUS_THREW_ERROR |
01867                            THREAD_STATUS_THREW_THROWABLE))
01868         {
01869             /*
01870              * Utilizing the current contents of the @c @b longjmp(3)
01871              * condition found in @b pThrowableEvent, which will
01872              * have been set when one of the status bits was set--
01873              * see @link jvm/src/threadutil.c threadutil.c@endlink
01874              * for several examples.
01875              *
01876              * When loading the error class, process its
01877              * @c @b <clinit> on any available thread, but process
01878              * its @C @b <init> on @e this thread so thread will be
01879              * done running after it has been processed (due to FP
01880              * change).
01881              */
01882             opcode_load_run_throwable(pThrowableEvent, thridx);
01883 
01884             /*
01885              * All conditions except java.lang.Exception should kill
01886              * the thread.
01887              *
01888              */
01889             if (!(THREAD_STATUS_THREW_EXCEPTION & nonlocal_rc))
01890             {
01891                 /* Attempt to shut down thread due to code completion */
01892                 if (rfalse == threadstate_request_complete(thridx))
01893                 {
01894                     sysErrMsg("opcode_run",
01895                      "Unable to move aborted thread %d to '%s' state",
01896                               thridx,
01897                               thread_state_get_name(
01898                                                 THREAD_STATE_COMPLETE));
01899                     THREAD_REQUEST_NEXT_STATE(badlogic, thridx);
01900 
01901                     return(rfalse);
01902                 }
01903             }
01904 
01905         } /* if nonlocal_rc */
01906 
01907     } /* if thread_exception_setup() */
01908     /***************************************************************/
01909     /***************************************************************/
01910     /***************************************************************/
01911     /***************************************************************/
01912     /***************************************************************/
01913     /* BEGIN GIANT SWITCH STATEMENT if(){}else{while(){switch()}} **/
01914     /***************************************************************/
01915     /***************************************************************/
01916     /***************************************************************/
01917     /***************************************************************/
01918     /***************************************************************/
01919     else
01920     {
01921         /*
01922          * Run inner JVM execution loop.
01923          */
01924 
01925         /*
01926          * Scratch area for operating the inner loop
01927          * and its key associations
01928          */
01929         jvm_pc             *pc    = THIS_PC(thridx);
01930         ClassFile          *pcfs  = THIS_PCFS(thridx);
01931         jvm_virtual_opcode *pcode = DEREFERENCE_PC_CODE_BASE(thridx);
01932 
01933         /* Scratch area for operand resolution */
01934         rboolean           iswide;
01935         iswide = rfalse;
01936 
01937         jvm_virtual_opcode opcode;
01938         u1                 op1u1idx; /* Operand 1 as a (u1) CP index */
01939         u2                 op1u2idx; /* Operand 1 as a (u2) CP index */
01940         u4                 op1u4off; /* Operand 1 as a (u4) offset */
01941 
01942         jint               jitmp1;  /* Opcode (jint) scratch area 1 */
01943         jint               jitmp2;  /* Opcode (jint) scratch area 2 */
01944         jlong              jltmp;   /* Opcode (jlong) scratch area */
01945         jfloat             jftmp;   /* Opcode (jfloat) scratch area */
01946         jdouble            jdtmp;   /* Opcode (jdouble) scratch area */
01947 
01948 
01949         /* Scratch area for Fieldref and Methodref navigation */
01950         cp_info_dup               *pcpd;
01951         CONSTANT_Class_info       *pcpd_Class;
01952         CONSTANT_Fieldref_info    *pcpd_Fieldref;
01953         CONSTANT_Methodref_info   *pcpd_Methodref;
01954         CONSTANT_NameAndType_info *pcpd_NameAndType;
01955         CONSTANT_Utf8_info        *pcpd_Utf8;
01956 
01957         field_info              *pfld;
01958         method_info             *pmth;
01959 
01960         ClassFile              *pcfsmisc;
01961         u2                      cpidxmisc;
01962         jvm_class_index         clsidxmisc;
01963         jvm_method_index        mthidxmisc;
01964         jvm_object_hash         objhashmisc;
01965         jvm_field_lookup_index  fluidxmisc;
01966         rchar                   *prchar_clsname;
01967         rushort                 special_obj_misc;
01968 
01969 
01970         /* Calls @c @b setjmp(3) to arm handler */
01971         nonlocal_thread_return = opcode_end_thread_setup();
01972 
01973         /* Show error case first due to @e long switch() following */
01974         if (EXIT_MAIN_OKAY != nonlocal_thread_return)
01975         {
01976             ; /* Nothing to do since this is not an error. */
01977         }
01978         else
01979         {
01980 
01981             /*!
01982              * @internal For best runtime efficiency, place tests in
01983              * order of most to least frequent occurrence.
01984              */
01985 
01986             while ( /* This thread is in the RUNNING state */
01987                    (THREAD_STATE_RUNNING == THREAD(thridx).this_state)&&
01988 
01989                    /* Time slice is still running or is N/A */
01990                    ((rfalse == check_timeslice) || /* or if true and */
01991                     (rfalse == pjvm->timeslice_expired)))
01992             {
01993                 /* Retrieve next virtual opcode */
01994                 opcode = pcode[pc->offset++];
01995 
01996 /*
01997  * Due to the significant complexity of this @c @b switch
01998  * statement, the indentation is being reset to permit wider lines
01999  * of code with out breaking up expressions with the intention of
02000  * creating better readability of the code.
02001  */
02002 
02003 static void dummy1(void) { char *p, *dummy2; dummy2 = p; dummy1(); }
02004 #define STUB { dummy1(); }
02005 
02006 switch(opcode)
02007 {
02008 case OPCODE_00_NOP:         /* Do nothing */
02009     break;
02010 
02011 case OPCODE_01_ACONST_NULL: /* Push NULL onto stack */
02012     /*! @todo Test this opcode */
02013     STUB;
02014     PUSH(thridx, FORCE_JINT(jvm_object_hash_null));
02015     break;
02016 
02017 case OPCODE_02_ICONST_M1:   /* Push constant -1, 0, 1, 2, 3, 4, 5 */
02018 case OPCODE_03_ICONST_0:
02019 case OPCODE_04_ICONST_1:
02020 case OPCODE_05_ICONST_2:
02021 case OPCODE_06_ICONST_3:
02022 case OPCODE_07_ICONST_4:
02023 case OPCODE_08_ICONST_5:
02024     PUSH(thridx, (((jint) opcode) - ((jint) OPCODE_03_ICONST_0)));
02025     break;
02026 
02027 case OPCODE_09_LCONST_0:
02028 case OPCODE_0A_LCONST_1:
02029     /*! @todo Test this opcode */
02030     STUB;
02031     jltmp = (((jlong) opcode) - ((jlong) OPCODE_09_LCONST_0));
02032 
02033     bytegames_split_jlong(jltmp, &jitmp1, &jitmp2);
02034 
02035     PUSH(thridx, jitmp1); /* ms word */
02036     PUSH(thridx, jitmp2); /* ls word */
02037     break;
02038 
02039 case OPCODE_0B_FCONST_0:
02040 case OPCODE_0C_FCONST_1:
02041 case OPCODE_0D_FCONST_2:
02042     /*! @todo Test this opcode */
02043     STUB;
02044     jftmp = (jfloat) (((jint) opcode) - ((jint) OPCODE_0B_FCONST_0));
02045 
02046     PUSH(thridx, FORCE_JINT(jftmp));
02047     break;
02048 
02049 case OPCODE_0E_DCONST_0:
02050 case OPCODE_0F_DCONST_1:
02051     /*! @todo Test this opcode */
02052     STUB;
02053     jdtmp = (jdouble) (((jint) opcode) - ((jint) OPCODE_0E_DCONST_0));
02054 
02055     bytegames_split_jdouble(jltmp, &jitmp1, &jitmp2);
02056 
02057     PUSH(thridx, jitmp1); /* ms word */
02058     PUSH(thridx, jitmp2); /* ls word */
02059 
02060     break;
02061 
02062 case OPCODE_10_BIPUSH:
02063     /*! @todo Write this opcode */
02064     STUB;
02065     break;
02066 
02067 case OPCODE_11_SIPUSH:
02068     /*! @todo Write this opcode */
02069     STUB;
02070     break;
02071 
02072 case OPCODE_12_LDC:
02073     /*! @todo Write this opcode */
02074     STUB;
02075     break;
02076 
02077 case OPCODE_13_LDC_W:
02078     /*! @todo Write this opcode */
02079     STUB;
02080     break;
02081 
02082 case OPCODE_14_LDC2_W:
02083     /*! @todo Write this opcode */
02084     STUB;
02085     break;
02086 
02087 case OPCODE_15_ILOAD:
02088     /*! @todo Write this opcode */
02089     STUB;
02090     iswide = rfalse;
02091     break;
02092 
02093 case OPCODE_16_LLOAD:
02094     /*! @todo Write this opcode */
02095     STUB;
02096     iswide = rfalse;
02097     break;
02098 
02099 case OPCODE_17_FLOAD:
02100     /*! @todo Write this opcode */
02101     STUB;
02102     iswide = rfalse;
02103     break;
02104 
02105 case OPCODE_18_DLOAD:
02106     /*! @todo Write this opcode */
02107     STUB;
02108     iswide = rfalse;
02109     break;
02110 
02111 case OPCODE_19_ALOAD:
02112     /*! @todo Write this opcode */
02113     STUB;
02114     iswide = rfalse;
02115     break;
02116 
02117 case OPCODE_1A_ILOAD_0:
02118 case OPCODE_1B_ILOAD_1:
02119 case OPCODE_1C_ILOAD_2:
02120 case OPCODE_1D_ILOAD_3:
02121     /*! @todo Write this opcode */
02122     STUB;
02123     break;
02124 
02125 case OPCODE_1E_LLOAD_0:
02126 case OPCODE_1F_LLOAD_1:
02127 case OPCODE_20_LLOAD_2:
02128 case OPCODE_21_LLOAD_3:
02129     /*! @todo Write this opcode */
02130     STUB;
02131     break;
02132 
02133 case OPCODE_22_FLOAD_0:
02134 case OPCODE_23_FLOAD_1:
02135 case OPCODE_24_FLOAD_2:
02136 case OPCODE_25_FLOAD_3:
02137     /*! @todo Write this opcode */
02138     STUB;
02139     break;
02140 
02141 case OPCODE_26_DLOAD_0:
02142 case OPCODE_27_DLOAD_1:
02143 case OPCODE_28_DLOAD_2:
02144 case OPCODE_29_DLOAD_3:
02145     /*! @todo Write this opcode */
02146     STUB;
02147     break;
02148 
02149 case OPCODE_2A_ALOAD_0:
02150 case OPCODE_2B_ALOAD_1:
02151 case OPCODE_2C_ALOAD_2:
02152 case OPCODE_2D_ALOAD_3:
02153     /*! @todo Write this opcode */
02154     STUB;
02155     break;
02156 
02157 case OPCODE_2E_IALOAD:
02158     /*! @todo Write this opcode */
02159     STUB;
02160     break;
02161 
02162 case OPCODE_2F_LALOAD:
02163     /*! @todo Write this opcode */
02164     STUB;
02165     break;
02166 
02167 case OPCODE_30_FALOAD:
02168     /*! @todo Write this opcode */
02169     STUB;
02170     break;
02171 
02172 case OPCODE_31_DALOAD:
02173     /*! @todo Write this opcode */
02174     STUB;
02175     break;
02176 
02177 case OPCODE_32_AALOAD:
02178     /*! @todo Write this opcode */
02179     STUB;
02180     break;
02181 
02182 case OPCODE_33_BALOAD:
02183     /*! @todo Write this opcode */
02184     STUB;
02185     break;
02186 
02187 case OPCODE_34_CALOAD:
02188     /*! @todo Write this opcode */
02189     STUB;
02190     break;
02191 
02192 case OPCODE_35_SALOAD:
02193     /*! @todo Write this opcode */
02194     STUB;
02195     break;
02196 
02197 case OPCODE_36_ISTORE:
02198     /*! @todo Write this opcode */
02199     STUB;
02200     iswide = rfalse;
02201     break;
02202 
02203 case OPCODE_37_LSTORE:
02204     /*! @todo Write this opcode */
02205     STUB;
02206     iswide = rfalse;
02207     break;
02208 
02209 case OPCODE_38_FSTORE:
02210     /*! @todo Write this opcode */
02211     STUB;
02212     iswide = rfalse;
02213     break;
02214 
02215 case OPCODE_39_DSTORE:
02216     /*! @todo Write this opcode */
02217     STUB;
02218     iswide = rfalse;
02219     break;
02220 
02221 case OPCODE_3A_ASTORE:
02222     /*! @todo Write this opcode */
02223     STUB;
02224     iswide = rfalse;
02225     break;
02226 
02227 case OPCODE_3B_ISTORE_0:
02228 case OPCODE_3C_ISTORE_1:
02229 case OPCODE_3D_ISTORE_2:
02230 case OPCODE_3E_ISTORE_3:
02231     /*! @todo Write this opcode */
02232     STUB;
02233     break;
02234 
02235 case OPCODE_3F_LSTORE_0:
02236 case OPCODE_40_LSTORE_1:
02237 case OPCODE_41_LSTORE_2:
02238 case OPCODE_42_LSTORE_3:
02239     /*! @todo Write this opcode */
02240     STUB;
02241     break;
02242 
02243 case OPCODE_43_FSTORE_0:
02244 case OPCODE_44_FSTORE_1:
02245 case OPCODE_45_FSTORE_2:
02246 case OPCODE_46_FSTORE_3:
02247     /*! @todo Write this opcode */
02248     STUB;
02249     break;
02250 
02251 case OPCODE_47_DSTORE_0:
02252 case OPCODE_48_DSTORE_1:
02253 case OPCODE_49_DSTORE_2:
02254 case OPCODE_4A_DSTORE_3:
02255     /*! @todo Write this opcode */
02256     STUB;
02257     break;
02258 
02259 case OPCODE_4B_ASTORE_0:
02260 case OPCODE_4C_ASTORE_1:
02261 case OPCODE_4D_ASTORE_2:
02262 case OPCODE_4E_ASTORE_3:
02263     /*! @todo Write this opcode */
02264     STUB;
02265     break;
02266 
02267 case OPCODE_4F_IASTORE:
02268     /*! @todo Write this opcode */
02269     STUB;
02270     break;
02271 
02272 case OPCODE_50_LASTORE:
02273     /*! @todo Write this opcode */
02274     STUB;
02275     break;
02276 
02277 case OPCODE_51_FASTORE:
02278     /*! @todo Write this opcode */
02279     STUB;
02280     break;
02281 
02282 case OPCODE_52_DASTORE:
02283     /*! @todo Write this opcode */
02284     STUB;
02285     break;
02286 
02287 case OPCODE_53_AASTORE:
02288     /*! @todo Write this opcode */
02289     STUB;
02290     break;
02291 
02292 case OPCODE_54_BASTORE:
02293     /*! @todo Write this opcode */
02294     STUB;
02295     break;
02296 
02297 case OPCODE_55_CASTORE:
02298     /*! @todo Write this opcode */
02299     STUB;
02300     break;
02301 
02302 case OPCODE_56_SASTORE:
02303     /*! @todo Write this opcode */
02304     STUB;
02305     break;
02306 
02307 case OPCODE_57_POP:
02308     /*! @todo Write this opcode */
02309     STUB;
02310     break;
02311 
02312 case OPCODE_58_POP2:
02313     /*! @todo Write this opcode */
02314     STUB;
02315     break;
02316 
02317 case OPCODE_59_DUP:
02318     /*! @todo Write this opcode */
02319     STUB;
02320     break;
02321 
02322 case OPCODE_5A_DUP_X1:
02323     /*! @todo Write this opcode */
02324     STUB;
02325     break;
02326 
02327 case OPCODE_5B_DUP_X2:
02328     /*! @todo Write this opcode */
02329     STUB;
02330     break;
02331 
02332 case OPCODE_5C_DUP2:
02333     /*! @todo Write this opcode */
02334     STUB;
02335     break;
02336 
02337 case OPCODE_5D_DUP2_X1:
02338     /*! @todo Write this opcode */
02339     STUB;
02340     break;
02341 
02342 case OPCODE_5E_DUP2_X2:
02343     /*! @todo Write this opcode */
02344     STUB;
02345     break;
02346 
02347 case OPCODE_5F_SWAP:
02348     /*! @todo Write this opcode */
02349     STUB;
02350     break;
02351 
02352 case OPCODE_60_IADD:
02353     /*! @todo Write this opcode */
02354     STUB;
02355     break;
02356 
02357 case OPCODE_61_LADD:
02358     /*! @todo Write this opcode */
02359     STUB;
02360     break;
02361 
02362 case OPCODE_62_FADD:
02363     /*! @todo Write this opcode */
02364     STUB;
02365     break;
02366 
02367 case OPCODE_63_DADD:
02368     /*! @todo Write this opcode */
02369     STUB;
02370     break;
02371 
02372 case OPCODE_64_ISUB:
02373     /*! @todo Write this opcode */
02374     STUB;
02375     break;
02376 
02377 case OPCODE_65_LSUB:
02378     /*! @todo Write this opcode */
02379     STUB;
02380     break;
02381 
02382 case OPCODE_66_FSUB:
02383     /*! @todo Write this opcode */
02384     STUB;
02385     break;
02386 
02387 case OPCODE_67_DSUB:
02388     /*! @todo Write this opcode */
02389     STUB;
02390     break;
02391 
02392 case OPCODE_68_IMUL:
02393     /*! @todo Write this opcode */
02394     STUB;
02395     break;
02396 
02397 case OPCODE_69_LMUL:
02398     /*! @todo Write this opcode */
02399     STUB;
02400     break;
02401 
02402 case OPCODE_6A_FMUL:
02403     /*! @todo Write this opcode */
02404     STUB;
02405     break;
02406 
02407 case OPCODE_6B_DMUL:
02408     /*! @todo Write this opcode */
02409     STUB;
02410     break;
02411 
02412 case OPCODE_6C_IDIV:
02413     /*! @todo Write this opcode */
02414     STUB;
02415     break;
02416 
02417 case OPCODE_6D_LDIV:
02418     /*! @todo Write this opcode */
02419     STUB;
02420     break;
02421 
02422 case OPCODE_6E_FDIV:
02423     /*! @todo Write this opcode */
02424     STUB;
02425     break;
02426 
02427 case OPCODE_6F_DDIV:
02428     /*! @todo Write this opcode */
02429     STUB;
02430     break;
02431 
02432 case OPCODE_70_IREM:
02433     /*! @todo Write this opcode */
02434     STUB;
02435     break;
02436 
02437 case OPCODE_71_LREM:
02438     /*! @todo Write this opcode */
02439     STUB;
02440     break;
02441 
02442 case OPCODE_72_FREM:
02443     /*! @todo Write this opcode */
02444     STUB;
02445     break;
02446 
02447 case OPCODE_73_DREM:
02448     /*! @todo Write this opcode */
02449     STUB;
02450     break;
02451 
02452 case OPCODE_74_INEG:
02453     /*! @todo Write this opcode */
02454     STUB;
02455     break;
02456 
02457 case OPCODE_75_LNEG:
02458     /*! @todo Write this opcode */
02459     STUB;
02460     break;
02461 
02462 case OPCODE_76_FNEG:
02463     /*! @todo Write this opcode */
02464     STUB;
02465     break;
02466 
02467 case OPCODE_77_DNEG:
02468     /*! @todo Write this opcode */
02469     STUB;
02470     break;
02471 
02472 case OPCODE_78_ISHL:
02473     /*! @todo Write this opcode */
02474     STUB;
02475     break;
02476 
02477 case OPCODE_79_LSHL:
02478     /*! @todo Write this opcode */
02479     STUB;
02480     break;
02481 
02482 case OPCODE_7A_ISHR:
02483     /*! @todo Write this opcode */
02484     STUB;
02485     break;
02486 
02487 case OPCODE_7B_LSHR:
02488     /*! @todo Write this opcode */
02489     STUB;
02490     break;
02491 
02492 case OPCODE_7C_IUSHR:
02493     /*! @todo Write this opcode */
02494     STUB;
02495     break;
02496 
02497 case OPCODE_7D_LUSHR:
02498     /*! @todo Write this opcode */
02499     STUB;
02500     break;
02501 
02502 case OPCODE_7E_IAND:
02503     /*! @todo Write this opcode */
02504     STUB;
02505     break;
02506 
02507 case OPCODE_7F_LAND:
02508     /*! @todo Write this opcode */
02509     STUB;
02510     break;
02511 
02512 case OPCODE_80_IOR:
02513     /*! @todo Write this opcode */
02514     STUB;
02515     break;
02516 
02517 case OPCODE_81_LOR:
02518     /*! @todo Write this opcode */
02519     STUB;
02520     break;
02521 
02522 case OPCODE_82_IXOR:
02523     /*! @todo Write this opcode */
02524     STUB;
02525     break;
02526 
02527 case OPCODE_83_LXOR:
02528     /*! @todo Write this opcode */
02529     STUB;
02530     break;
02531 
02532 case OPCODE_84_IINC:
02533     /*! @todo Write this opcode */
02534     STUB;
02535     break;
02536 
02537 case OPCODE_85_I2L:
02538     /*! @todo Write this opcode */
02539     STUB;
02540     break;
02541 
02542 case OPCODE_86_I2F:
02543     /*! @todo Write this opcode */
02544     STUB;
02545     break;
02546 
02547 case OPCODE_87_I2D:
02548     /*! @todo Write this opcode */
02549     STUB;
02550     break;
02551 
02552 case OPCODE_88_L2I:
02553     /*! @todo Write this opcode */
02554     STUB;
02555     break;
02556 
02557 case OPCODE_89_L2F:
02558     /*! @todo Write this opcode */
02559     STUB;
02560     break;
02561 
02562 case OPCODE_8A_L2D:
02563     /*! @todo Write this opcode */
02564     STUB;
02565     break;
02566 
02567 case OPCODE_8B_F2I:
02568     /*! @todo Write this opcode */
02569     STUB;
02570     break;
02571 
02572 case OPCODE_8C_F2L:
02573     /*! @todo Write this opcode */
02574     STUB;
02575     break;
02576 
02577 case OPCODE_8D_F2D:
02578     /*! @todo Write this opcode */
02579     STUB;
02580     break;
02581 
02582 case OPCODE_8E_D2I:
02583     /*! @todo Write this opcode */
02584     STUB;
02585     break;
02586 
02587 case OPCODE_8F_D2L:
02588     /*! @todo Write this opcode */
02589     STUB;
02590     break;
02591 
02592 case OPCODE_90_D2F:
02593     /*! @todo Write this opcode */
02594     STUB;
02595     break;
02596 
02597 case OPCODE_91_I2B:
02598     /*! @todo Write this opcode */
02599     STUB;
02600     break;
02601 
02602 case OPCODE_92_I2C:
02603     /*! @todo Write this opcode */
02604     STUB;
02605     break;
02606 
02607 case OPCODE_93_I2S:
02608     /*! @todo Write this opcode */
02609     STUB;
02610     break;
02611 
02612 case OPCODE_94_LCMP:
02613     /*! @todo Write this opcode */
02614     STUB;
02615     break;
02616 
02617 case OPCODE_95_FCMPL:
02618     /*! @todo Write this opcode */
02619     STUB;
02620     break;
02621 
02622 case OPCODE_96_FCMPG:
02623     /*! @todo Write this opcode */
02624     STUB;
02625     break;
02626 
02627 case OPCODE_97_DCMPL:
02628     /*! @todo Write this opcode */
02629     STUB;
02630     break;
02631 
02632 case OPCODE_98_DCMPG:
02633     /*! @todo Write this opcode */
02634     STUB;
02635     break;
02636 
02637 case OPCODE_99_IFEQ:
02638     /*! @todo Write this opcode */
02639     STUB;
02640     break;
02641 
02642 case OPCODE_9A_IFNE:
02643     /*! @todo Write this opcode */
02644     STUB;
02645     break;
02646 
02647 case OPCODE_9B_IFLT:
02648     /*! @todo Write this opcode */
02649     STUB;
02650     break;
02651 
02652 case OPCODE_9C_IFGE:
02653     /*! @todo Write this opcode */
02654     STUB;
02655     break;
02656 
02657 case OPCODE_9D_IFGT:
02658     /*! @todo Write this opcode */
02659     STUB;
02660     break;
02661 
02662 case OPCODE_9E_IFLE:
02663     /*! @todo Write this opcode */
02664     STUB;
02665     break;
02666 
02667 case OPCODE_9F_IF_ICMPEQ:
02668     /*! @todo Write this opcode */
02669     STUB;
02670     break;
02671 
02672 case OPCODE_A0_IF_ICMPNE:
02673     /*! @todo Write this opcode */
02674     STUB;
02675     break;
02676 
02677 case OPCODE_A1_IF_ICMPLT:
02678     /*! @todo Write this opcode */
02679     STUB;
02680     break;
02681 
02682 case OPCODE_A2_IF_ICMPGE:
02683     /*! @todo Write this opcode */
02684     STUB;
02685     break;
02686 
02687 case OPCODE_A3_IF_ICMPGT:
02688     /*! @todo Write this opcode */
02689     STUB;
02690     break;
02691 
02692 case OPCODE_A4_IF_ICMPLE:
02693     /*! @todo Write this opcode */
02694     STUB;
02695     break;
02696 
02697 case OPCODE_A5_IF_ACMPEQ:
02698     /*! @todo Write this opcode */
02699     STUB;
02700     break;
02701 
02702 case OPCODE_A6_IF_ACMPNE:
02703     /*! @todo Write this opcode */
02704     STUB;
02705     break;
02706 
02707 case OPCODE_A7_GOTO:
02708     /*! @todo Write this opcode */
02709     STUB;
02710     break;
02711 
02712 case OPCODE_A8_JSR:
02713     /*! @todo Write this opcode */
02714     STUB;
02715     break;
02716 
02717 case OPCODE_A9_RET:
02718     /*! @todo Write this opcode */
02719     STUB;
02720     iswide = rfalse;
02721 
02722     /*!
02723      * @todo  Is this test needed here,
02724      *         or only in @b xRETURN ?
02725      */
02726     opcode_end_thread_test(thridx);
02727     break;
02728 
02729 case OPCODE_AA_TABLESWITCH:
02730     STUB;
02731     break;
02732 
02733 case OPCODE_AB_LOOKUPSWITCH:
02734     /*! @todo Write this opcode */
02735     STUB;
02736     break;
02737 
02738 case OPCODE_AC_IRETURN:
02739     /*! @todo Write this opcode */
02740     STUB;
02741     opcode_end_thread_test(thridx);
02742     break;
02743 
02744     /*! @todo Write this opcode */
02745 case OPCODE_AD_LRETURN:
02746     STUB;
02747     opcode_end_thread_test(thridx);
02748     break;
02749     /*! @todo Write this opcode */
02750 
02751 case OPCODE_AE_FRETURN:
02752     STUB;
02753     opcode_end_thread_test(thridx);
02754     /*! @todo Write this opcode */
02755     break;
02756 
02757 case OPCODE_AF_DRETURN:
02758     STUB;
02759     /*! @todo Write this opcode */
02760     opcode_end_thread_test(thridx);
02761     break;
02762 
02763 case OPCODE_B0_ARETURN:
02764     /*! @todo Write this opcode */
02765     STUB;
02766     opcode_end_thread_test(thridx);
02767     break;
02768 
02769 case OPCODE_B1_RETURN:
02770 
02771     CALCULATE_METHOD_INFO_FROM_PC;
02772 
02773     /*
02774      * If synchronized method, release MLOCK.
02775      */
02776     if (ACC_SYNCHRONIZED & pmth->access_flags)
02777     {
02778         (rvoid) objectutil_unsynchronize(
02779                     CLASS(clsidxmisc).class_objhash,
02780                     CURRENT_THREAD);
02781     }
02782 
02783     /*!
02784      * @todo  Implement test for same number of locks/unlocks
02785      *        per JVM spec section 8.13.
02786      */
02787 
02788     POP_FRAME(thridx);
02789 /*
02790 ... Don't forget to set these to old method:
02791         pcfs  = THIS_PCFS(thridx);
02792         pcode = DEREFERENCE_PC_CODE_BASE(thridx);
02793 */
02794     opcode_end_thread_test(thridx);
02795     break;
02796 
02797 case OPCODE_B2_GETSTATIC:
02798 
02799     /* Retrieve the constant_pool (u2) operand */
02800     GET_U2_OPERAND(op1u2idx);
02801 
02802     /* Must reference a field */
02803     CHECK_CP_TAG(op1u2idx, CONSTANT_Fieldref);
02804 
02805     /* calc clsidxmisc and pcpd and pcpd_Fieldref */
02806     CALCULATE_FIELD_INFO_FROM_FIELD_REFERENCE(op1u2idx);
02807 
02808     /* Must be a valid reference to a method */
02809     CHECK_VALID_FIELDLOOKUPIDX(fluidxmisc);
02810 
02811     /* Must be a static field */
02812     CHECK_STATIC_FIELD;
02813 
02814     /* If it is a final field, it must be in the current class */
02815     CHECK_FINAL_FIELD_CURRENT_CLASS;
02816 
02817     /* Retrieve data from the static field now */
02818     GETSTATIC;
02819 
02820     break;
02821 
02822 case OPCODE_B3_PUTSTATIC:
02823 
02824     /* Retrieve the constant_pool (u2) operand */
02825     GET_U2_OPERAND(op1u2idx);
02826 
02827     /* Must reference a field */
02828     CHECK_CP_TAG(op1u2idx, CONSTANT_Fieldref);
02829 
02830     /* calc clsidxmisc and pcpd and pcpd_Fieldref */
02831     CALCULATE_FIELD_INFO_FROM_FIELD_REFERENCE(op1u2idx);
02832 
02833     /* Must be a valid reference to a method */
02834     CHECK_VALID_FIELDLOOKUPIDX(fluidxmisc);
02835 
02836     /* Must be a static field */
02837     CHECK_STATIC_FIELD;
02838 
02839     /* If it is a final field, it must be in the current class */
02840     CHECK_FINAL_FIELD_CURRENT_CLASS;
02841 
02842     /* Store data into the static field now */
02843     PUTSTATIC;
02844 
02845     break;
02846 
02847 case OPCODE_B4_GETFIELD:
02848     /*! @todo Write this opcode */
02849     STUB;
02850     break;
02851 
02852 case OPCODE_B5_PUTFIELD:
02853     /*! @todo Write this opcode */
02854     STUB;
02855     break;
02856 
02857 case OPCODE_B6_INVOKEVIRTUAL:
02858     /*! @todo Write this opcode */
02859     STUB;
02860     break;
02861 
02862 case OPCODE_B7_INVOKESPECIAL:
02863     /*! @todo Write this opcode */
02864     STUB;
02865     break;
02866 
02867 case OPCODE_B8_INVOKESTATIC:
02868 
02869     /* Retrieve the constant_pool (u2) operand */
02870     GET_U2_OPERAND(op1u2idx);
02871 
02872     /* Must reference a method */
02873     CHECK_CP_TAG(op1u2idx, CONSTANT_Methodref);
02874 
02875     /* calc clsidxmisc and pcpd and pcpd_Methodref */
02876     CALCULATE_METHOD_INFO_FROM_METHOD_REFERENCE(op1u2idx);
02877 
02878     /* Must be a valid reference to a method */
02879     CHECK_VALID_CODEATRIDX(pcpd_Methodref
02880                              ->LOCAL_Methodref_binding.codeatridxJVM);
02881 
02882     /* Must be a static method */
02883     CHECK_STATIC_METHOD;
02884 
02885     /* Must not be an abstract method */
02886     CHECK_NOT_ABSTRACT_METHOD;
02887 
02888     /*
02889      * If synchronized method, attempt to gain MLOCK.
02890      * If successful, carry on with opcode.  If not,
02891      * unwind PC to beginning of instruction and
02892      * quit.  The thread model will re-enter the
02893      * opcode when the lock has been acquired. 
02894      */
02895     if (ACC_SYNCHRONIZED & pmth->access_flags)
02896     {
02897         if (rfalse == objectutil_synchronize(
02898                           CLASS(clsidxmisc).class_objhash,
02899                           CURRENT_THREAD))
02900         {
02901             pc->offset -= sizeof(u1); /* size of opcode */
02902             pc->offset -= sizeof(u2); /* size of operand */
02903             break;
02904         }
02905     }
02906 
02907     if (ACC_NATIVE & pmth->access_flags)
02908     {
02909         cpidxmisc        = pcpd_Methodref->name_and_type_index;
02910         pcpd             = pcfs->constant_pool[cpidxmisc];
02911         pcpd_NameAndType = PTR_THIS_CP_NameAndType(pcpd);
02912 
02913         native_run_method(CURRENT_THREAD,
02914                           pcpd_Methodref
02915                             ->LOCAL_Methodref_binding
02916                               .nmordJVM,
02917                           clsidxmisc,
02918                           pcpd_NameAndType->name_index,
02919                           pcpd_NameAndType->descriptor_index);
02920     }
02921     else
02922     {
02923         ; /* Start up Java code */
02924 /*
02925 ... Don't forget to set these to new method:
02926         pcfs  = THIS_PCFS(thridx);
02927         pcode = DEREFERENCE_PC_CODE_BASE(thridx);
02928 */
02929     }
02930     break;
02931 
02932 case OPCODE_B9_INVOKEINTERFACE:
02933     /*! @todo Write this opcode */
02934     STUB;
02935     break;
02936 
02937 case OPCODE_BA_XXXUNUSEDXXX1:
02938    goto unused_reserved_opcodes; /* Gag!  But it makes sense here */
02939 
02940 case OPCODE_BB_NEW:
02941 
02942     /* Retrieve the constant_pool (u2) operand */
02943     GET_U2_OPERAND(op1u2idx);
02944 
02945     /* Must reference a normal class, not an array or interface class */
02946     CHECK_CP_TAG(op1u2idx, CONSTANT_Class);
02947     CHECK_NOT_ABSTRACT_CLASS;
02948     CHECK_NOT_ARRAY_OBJECT;
02949     CHECK_NOT_INTERFACE_CLASS;
02950 
02951     /* calc clsidxmisc and pcpd and pcpd_Class and pcfsmisc */
02952 #if 0
02953     CALCULATE_CLASS_INFO_FROM_CLASS_REFERENCE(op1u2idx);
02954 #else
02955     pcpd       = pcfs->constant_pool[op1u2idx];
02956     pcpd_Class = PTR_THIS_CP_Class(pcpd);
02957     clsidxmisc = pcpd_Class->LOCAL_Class_binding.clsidxJVM;
02958     if (jvm_class_index_null == clsidxmisc)
02959     {
02960         /* Need local variable to avoid possible expansion confusion */
02961 
02962                                         /* pcpd_Class->name_index; */
02963         jvm_constant_pool_index cpidxOLD = op1u2idx;
02964 
02965         /* If class is not loaded, go retrieve it by UTF8 class name */
02966 #if 0  
02967         LATE_CLASS_LOAD(cpidxOLD);
02968 #else
02969 
02970         pcpd       = pcfs->constant_pool[cpidxOLD]; /* Class name */
02971         pcpd_Class = PTR_THIS_CP_Class(pcpd);
02972                                                       /* UTF8 string */
02973         pcpd       = pcfs->constant_pool[pcpd_Class->name_index];
02974         pcpd_Utf8  = PTR_THIS_CP_Utf8(pcpd);
02975                                                                       
02976         prchar_clsname = utf_utf2prchar(pcpd_Utf8);
02977                                                                       
02978         /* Try again to load class */
02979         clsidxmisc = class_load_resolve_clinit(prchar_clsname,
02980                                                CURRENT_THREAD,
02981                                                rfalse,
02982                                                rfalse);
02983         
02984         HEAP_FREE_DATA(prchar_clsname);
02985         
02986         /* If class is irretrievable, abort */
02987         if (jvm_class_index_null == clsidxmisc)
02988         {
02989             thread_throw_exception(thridx,
02990                                    THREAD_STATUS_THREW_ERROR,
02991                                JVMCLASS_JAVA_LANG_NOCLASSDEFFOUNDERROR);
02992 /*NOTREACHED*/
02993         }
02994 #endif
02995     }                                                                   
02996     pcfsmisc = CLASS_OBJECT_LINKAGE(clsidxmisc)->pcfs; /* Extra ; */
02997 #endif
02998 
02999     /* Create new object from this class */
03000     special_obj_misc = OBJECT_STATUS_EMPTY;
03001 
03002     if (0 == utf_prchar_classname_strcmp(JVMCLASS_JAVA_LANG_THREAD,
03003                                          pcfsmisc,
03004                                          pcfsmisc->this_class))
03005     {
03006         special_obj_misc |= OBJECT_STATUS_THREAD;
03007     }
03008 
03009     objhashmisc =
03010         object_instance_new(special_obj_misc,
03011                             pcfsmisc,
03012                             clsidxmisc,
03013                             0,
03014                             (rvoid *) rnull,
03015                             rfalse,
03016                             thridx);
03017 
03018     /* Store result to stack */
03019     PUSH(thridx, (jint) objhashmisc);
03020 
03021     break;
03022 
03023 case OPCODE_BC_NEWARRAY:
03024     /*! @todo Write this opcode */
03025     STUB;
03026     break;
03027 
03028 case OPCODE_BD_ANEWARRAY:
03029 
03030     /* Retrieve the constant_pool (u2) operand */
03031     GET_U2_OPERAND(op1u2idx);
03032 
03033     /*!
03034      * @todo Make sure that @e all of "class, array, or interface type"
03035      *       is supported by this test:
03036      */
03037 
03038     /* Must reference a class */
03039     CHECK_CP_TAG(op1u2idx, CONSTANT_Class);
03040     /* CHECK_CP_TAG2/3(op1u2idx, CONSTANT_Class,array? ,interface? ); */
03041 
03042     /* calc clsidxmisc and pcpd and pcpd_Class and pcfsmisc */
03043 #if 1
03044     CALCULATE_CLASS_INFO_FROM_CLASS_REFERENCE(op1u2idx);
03045 #else
03046     pcpd       = pcfs->constant_pool[op1u2idx];
03047     pcpd_Class = PTR_THIS_CP_Class(pcpd);
03048     clsidxmisc = pcpd_Class->LOCAL_Class_binding.clsidxJVM;
03049     if (jvm_class_index_null == clsidxmisc)
03050     {
03051         /* Need local variable to avoid possible expansion confusion */
03052 
03053                                            /* pcpd_Class->name_index; */
03054         jvm_constant_pool_index cpidxOLD = op1u2idx;
03055 
03056         /* If class is not loaded, go retrieve it by UTF8 class name */
03057 #if 0  
03058         LATE_CLASS_LOAD(cpidxOLD);
03059 #else
03060 
03061         pcpd       = pcfs->constant_pool[cpidxOLD]; /* Class name */
03062         pcpd_Class = PTR_THIS_CP_Class(pcpd);
03063                                                       /* UTF8 string */
03064         pcpd       = pcfs->constant_pool[pcpd_Class->name_index];
03065         pcpd_Utf8  = PTR_THIS_CP_Utf8(pcpd);
03066                                                                       
03067         prchar_clsname = utf_utf2prchar(pcpd_Utf8);
03068                                                                       
03069         /* Try again to load class */
03070         clsidxmisc = class_load_resolve_clinit(prchar_clsname,
03071                                                CURRENT_THREAD,
03072                                                rfalse,
03073                                                rfalse);
03074         
03075         HEAP_FREE_DATA(prchar_clsname);
03076         
03077         /* If class is irretrievable, abort */
03078         if (jvm_class_index_null == clsidxmisc)
03079         {
03080             thread_throw_exception(thridx,
03081                                    THREAD_STATUS_THREW_ERROR,
03082                                JVMCLASS_JAVA_LANG_NOCLASSDEFFOUNDERROR);
03083 /*NOTREACHED*/
03084         }
03085 #endif
03086     }                                                                   
03087     pcfsmisc = CLASS_OBJECT_LINKAGE(clsidxmisc)->pcfs; /* Extra ; */
03088 #endif
03089 
03090     /* Retrieve 'count' operand from TOS */
03091     POP(thridx, jitmp1, /* Redundant */ jint  );
03092 
03093     /* Cannot have negative number of array elements (zero is okay) */
03094     if (0 > jitmp1)
03095     {
03096         thread_throw_exception(thridx,
03097                                THREAD_STATUS_THREW_EXCEPTION,
03098                          JVMCLASS_JAVA_LANG_NEGATIVEARRAYSIZEEXCEPTION);
03099 /*NOTREACHED*/
03100     }
03101 
03102     /* Create new object from this class, array, or interface */
03103 #if 1
03104     special_obj_misc = OBJECT_STATUS_ARRAY;
03105 #else
03106     special_obj_misc = OBJECT_STATUS_EMPTY;
03107     if (CLASS_STATUS_ARRAY & CLASS(clsidxmisc).status)
03108     {
03109         special_obj_misc |= OBJECT_STATUS_ARRAY;
03110     }
03111 #endif
03112 
03113     if (0 == utf_prchar_classname_strcmp(JVMCLASS_JAVA_LANG_THREAD,
03114                                          pcfsmisc,
03115                                          pcfsmisc->this_class))
03116     {
03117         special_obj_misc |= OBJECT_STATUS_THREAD;
03118     }
03119 
03120     /* Notice that @b ANEWARRAY only handles a single array dimension */
03121     objhashmisc =
03122         object_instance_new(special_obj_misc,
03123                             pcfsmisc,
03124                             clsidxmisc,
03125                             ((OBJECT_STATUS_ARRAY & special_obj_misc)
03126                                  ? 1
03127                                  : 0),
03128                             &jitmp1,
03129                             rfalse, /*! @todo:  Is 'rfalse' correct? */
03130                             thridx);
03131 
03132     /* Store result to stack */
03133     PUSH(thridx, (jint) objhashmisc);
03134 
03135     break;
03136 
03137 case OPCODE_BE_ARRAYLENGTH:
03138     /*! @todo Write this opcode */
03139     STUB;
03140     break;
03141 
03142 case OPCODE_BF_ATHROW:
03143     /*! @todo Write this opcode */
03144     STUB;
03145     break;
03146 
03147 case OPCODE_C0_CHECKCAST:
03148     /*! @todo Write this opcode */
03149     STUB;
03150     break;
03151 
03152 case OPCODE_C1_INSTANCEOF:
03153     /*! @todo Write this opcode */
03154     STUB;
03155     break;
03156 
03157 case OPCODE_C2_MONITORENTER:
03158     /*! @todo Write this opcode */
03159     STUB;
03160     break;
03161 
03162 case OPCODE_C3_MONITOREXIT:
03163     /*! @todo Write this opcode */
03164     STUB;
03165     break;
03166 
03167 case OPCODE_C4_WIDE:
03168     /*! @todo Test this opcode */
03169     iswide = rtrue;  /* Will be read then cleared by other opcodes */
03170     break;
03171 
03172 case OPCODE_C5_MULTIANEWARRAY:
03173     /*! @todo Write this opcode */
03174     STUB;
03175     break;
03176 
03177 case OPCODE_C6_IFNULL:
03178     /*! @todo Write this opcode */
03179     STUB;
03180     break;
03181 
03182 case OPCODE_C7_IFNONNULL:
03183     /*! @todo Write this opcode */
03184     STUB;
03185     break;
03186 
03187 case OPCODE_C8_GOTO_W:
03188     /*! @todo Write this opcode */
03189     STUB;
03190     break;
03191 
03192 case OPCODE_C9_JSR_W:
03193     /*! @todo Write this opcode */
03194     STUB;
03195     break;
03196 
03197 
03198 /* Reserved opcodes: */
03199 case OPCODE_CA_BREAKPOINT:
03200     /*! @todo Write this opcode */
03201     STUB;
03202     break;
03203 
03204 
03205 /* Undefined and unused opcodes, reserved */
03206 case OPCODE_CB_UNUSED:
03207 case OPCODE_CC_UNUSED:
03208 case OPCODE_CD_UNUSED:
03209 case OPCODE_CE_UNUSED:
03210 case OPCODE_CF_UNUSED:
03211 
03212 case OPCODE_D0_UNUSED:
03213 case OPCODE_D1_UNUSED:
03214 case OPCODE_D2_UNUSED:
03215 case OPCODE_D3_UNUSED:
03216 case OPCODE_D4_UNUSED:
03217 case OPCODE_D5_UNUSED:
03218 case OPCODE_D6_UNUSED:
03219 case OPCODE_D7_UNUSED:
03220 case OPCODE_D8_UNUSED:
03221 case OPCODE_D9_UNUSED:
03222 case OPCODE_DA_UNUSED:
03223 case OPCODE_DB_UNUSED:
03224 case OPCODE_DC_UNUSED:
03225 case OPCODE_DD_UNUSED:
03226 case OPCODE_DE_UNUSED:
03227 case OPCODE_DF_UNUSED:
03228 
03229 case OPCODE_E0_UNUSED:
03230 case OPCODE_E1_UNUSED:
03231 case OPCODE_E2_UNUSED:
03232 case OPCODE_E3_UNUSED:
03233 case OPCODE_E4_UNUSED:
03234 case OPCODE_E5_UNUSED:
03235 case OPCODE_E6_UNUSED:
03236 case OPCODE_E7_UNUSED:
03237 case OPCODE_E8_UNUSED:
03238 case OPCODE_E9_UNUSED:
03239 case OPCODE_EA_UNUSED:
03240 case OPCODE_EB_UNUSED:
03241 case OPCODE_EC_UNUSED:
03242 case OPCODE_ED_UNUSED:
03243 case OPCODE_EE_UNUSED:
03244 case OPCODE_EF_UNUSED:
03245 
03246 case OPCODE_F0_UNUSED:
03247 case OPCODE_F1_UNUSED:
03248 case OPCODE_F2_UNUSED:
03249 case OPCODE_F3_UNUSED:
03250 case OPCODE_F4_UNUSED:
03251 case OPCODE_F5_UNUSED:
03252 case OPCODE_F6_UNUSED:
03253 case OPCODE_F7_UNUSED:
03254 case OPCODE_F8_UNUSED:
03255 case OPCODE_F9_UNUSED:
03256 case OPCODE_FA_UNUSED:
03257 case OPCODE_FB_UNUSED:
03258 case OPCODE_FC_UNUSED:
03259 case OPCODE_FD_UNUSED:
03260 
03261 /* Reserved opcodes: */
03262 case OPCODE_FE_IMPDEP1:
03263 
03264  unused_reserved_opcodes:
03265 
03266     /*! @todo Write this opcode */
03267     STUB;
03268     break;
03269 
03270 case OPCODE_FF_IMPDEP2:
03271     /*! @todo Write this opcode */
03272     STUB;
03273     break;
03274 
03275 } /* switch(opcode) */
03276 
03277 /* Renew indentation... */
03278 
03279             } /* while ... */
03280         } /* if nonlocal_thread_return else */
03281 
03282     } /* if thread_exception_setup() else */
03283 
03284     /***************************************************************/
03285     /***************************************************************/
03286     /***************************************************************/
03287     /***************************************************************/
03288     /***************************************************************/
03289     /* END OF GIANT SWITCH STATEMENT if(){}else{while(){switch()}}**/
03290     /***************************************************************/
03291     /***************************************************************/
03292     /***************************************************************/
03293     /***************************************************************/
03294     /***************************************************************/
03295 
03296     /* If the timer ticked, clear flag and process next thread */
03297     if((rtrue == check_timeslice) && (rtrue == pjvm->timeslice_expired))
03298     {
03299         pjvm->timeslice_expired = rfalse;
03300     }
03301 
03302     /*
03303      * If frame is empty, thread is done running, but if
03304      * @link #rthread.fp_end_program fp_end_program@endlink is being
03305      * used to control, say, a <cliinit> of a
03306      * @link #LATE_CLASS_LOAD() LATE_CLASS_LOAD@endlink, the thread is
03307      * still doing something even when the end-of-program indication
03308      * has occurred.  See also
03309      * @link #opcode_end_thread_test() opcode_end_thread_test()@endlink
03310      * for use of this same logic.
03311      *
03312      * Notice that this check does _not_ look for the fp-end-program
03313      * condition per @link #opcode_end_thread_test()
03314        opcode_end_thread_test()@endlink.  This means that the next
03315      * time this thread runs, execution will pick up with the next
03316      * instruction past a recent @c @b <clinit> or @c @b <init>
03317      * call.
03318      */
03319     if (CHECK_FINAL_STACK_FRAME_ULTIMATE(thridx) &&
03320         (THREAD_STATE_RUNNING == THREAD(thridx).this_state))
03321     {
03322         /* Attempt to shut down thread due to code completion */
03323         if (rfalse == threadstate_request_complete(thridx))
03324         {
03325             sysErrMsg("opcode_run",
03326              "Unable to move completed thread %d to '%s' state",
03327                       thridx,
03328                       thread_state_get_name(THREAD_STATE_COMPLETE));
03329             THREAD_REQUEST_NEXT_STATE(badlogic, thridx);
03330 
03331             return(rfalse);
03332         }
03333     }
03334 
03335     /*!
03336      * If a thread completed running, and a proper request to the
03337      * @b COMPLETE state was issued, then it finished normally.
03338      *
03339      * @todo Should this @c @b if() statement be inside of
03340      *       the block requesting @b COMPLETE state?  Should a
03341      *       simple @c @b return(rtrue) be there?  Should
03342      *       this @c @b if() statement be expanded to
03343      *       consider other conditions?  Etc.  Just needs review
03344      *       for other possibilities.
03345      */
03346     if (EXIT_JVM_THREAD == nonlocal_thread_return)
03347     {
03348         return(rtrue);
03349     }
03350 
03351     /*
03352      * Move unhandled condition (@b nonlocal_rc)
03353      * and "thread is finished running" (@b nonlocal_thread_return)
03354      * conditions to the @b COMPLETE state, otherwise everything
03355      * ran fine and thread is still in the @b RUNNING state.
03356      */
03357     if ((THREAD_STATUS_EMPTY == nonlocal_rc) &&
03358         (EXIT_MAIN_OKAY      == nonlocal_thread_return))
03359     {
03360         return(rtrue);
03361     }
03362     else
03363     {
03364         /* Attempt to shut down thread due to condition */
03365         if (rfalse == threadstate_request_complete(thridx))
03366         {
03367             sysErrMsg("opcode_run",
03368              "Unable to move completed thread %d to '%s' state",
03369                       thridx,
03370                       thread_state_get_name(THREAD_STATE_COMPLETE));
03371             THREAD_REQUEST_NEXT_STATE(badlogic, thridx);
03372 
03373             return(rfalse);
03374         }
03375         /* Return @link #rtrue rtrue@endlink if end of thread detected,
03376          * otherwise @link #rfalse rfalse@endlink because of unhandled
03377          * condition.
03378          */
03379         return(rfalse);
03380     }
03381 
03382 } /* END of opcode_run() */
03383 
03384 
03385 /* EOF */
03386 

Generated on Fri Sep 30 18:49:07 2005 by  doxygen 1.4.4