You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by dl...@apache.org on 2005/10/19 10:36:53 UTC
svn commit: r326473 [2/2] -
/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/opcode.c
Modified: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/opcode.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/opcode.c?rev=326473&r1=326472&r2=326473&view=diff
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/opcode.c (original)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/opcode.c Wed Oct 19 01:36:15 2005
@@ -147,1142 +147,68 @@
* </ul>
*
*
- * @todo The code fragment macros used by the opcode switch in
- * @link #opcode_run() opcode_run()@endlink need to have the
- * local variables documented as to which as required upon
- * macro startup and which are set for use at macro completion.
+ * @todo HARMONY-6-jvm-opcode.c-1 The code fragment macros used by
+ * the opcode switch in @link #opcode_run() opcode_run()@endlink
+ * need to have the local variables documented as to which as
+ * required upon macro startup and which are set for use at
+ * macro completion.
*
*
* @section Control
*
- * \$URL$ \$Id$
+ * \$URL$
*
- * Copyright 2005 The Apache Software Foundation
- * or its licensors, as applicable.
- *
- * Licensed under the Apache License, Version 2.0 ("the License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
- * either express or implied.
- *
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * @version \$LastChangedRevision$
- *
- * @date \$LastChangedDate$
- *
- * @author \$LastChangedBy$
- * Original code contributed by Daniel Lydick on 09/28/2005.
- *
- * @section Reference
- *
- */
-
-#include "arch.h"
-ARCH_COPYRIGHT_APACHE(opcode, c, "$URL$ $Id$");
-
-#include "jvmcfg.h"
-#include "cfmacros.h"
-#include "classfile.h"
-#include "exit.h"
-#include "gc.h"
-#include "jvm.h"
-#include "jvmclass.h"
-#include "linkage.h"
-#include "method.h"
-#include "native.h"
-#include "opcode.h"
-#include "utf.h"
-#include "util.h"
-
-/*!
- * @name Macro support for inner loop opcodes.
- *
- * @brief Common operations that are used in numerous opcodes
- * are gathered here so as to improve accuracy of implementation
- * and simplify the code.
- *
- */
-
-/*@{ */ /* Begin grouped definitions */
-
-/*!
- * @brief Retrieve a two-byte operand that the PC points to.
- *
- *
- * Store thw two-byte operand into the requested @link #u2 u2@endlink
- * variable, then increment the program counter to the next byte code
- * following it.
- *
- * @param u2var Name of a @link #u2 u2@endlink variable that will
- * receive the two bytes of operand from with the
- * instruction.
- *
- *
- * @returns @link #rvoid rvoid@endlink
- *
- */
-#define GET_U2_OPERAND(u2var) \
- u2var = GETRS2((u2 *) &pcode[pc->offset]); \
- pc->offset += sizeof(u2)
-
-
-/*!
- * @name Validate a constant_pool entry
- *
- */
-
-
-/*@{ */ /* Begin grouped definitions */
-
-/*!
- * @brief Check that a constant_pool entry contains
- * a specific of tag for this operation.
- *
- *
- * @param u2var Name of a @link #u2 u2@endlink variable that
- * contains a constant_pool entry to be examined.
- *
- * @param cptag1 First constant_pool tag that is valid for this
- * operation.
- *
- *
- * @returns @link #rvoid rvoid@endlink
- *
- *
- * @throws JVMCLASS_JAVA_LANG_VERIFYERROR
- * @link #JVMCLASS_JAVA_LANG_VERIFYERROR
- if the constant_pool entry does not have the right tag@endlink.
- *
- */
-#define CHECK_CP_TAG(u2var, cptag1) \
- if (cptag1 != CP_TAG(pcfs, u2var)) \
- { \
- /* Somebody is confused */ \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_VERIFYERROR); \
-/*NOTREACHED*/ \
- }
-
-
-/*!
- * @brief Check that a constant_pool entry contains
- * the right kind of tag for this operation, from a choice of two.
- *
- *
- * @param u2var Name of a @link #u2 u2@endlink variable that
- * contains a constant_pool entry to be examined.
- *
- * @param cptag1 First constant_pool tag that is valid for this
- * operation.
- *
- * @param cptag2 Second constant_pool tag that is valid for this
- * operation.
- *
- *
- * @returns @link #rvoid rvoid@endlink
- *
- *
- * @throws JVMCLASS_JAVA_LANG_VERIFYERROR
- * @link #JVMCLASS_JAVA_LANG_VERIFYERROR
- if the constant_pool entry does not have the right tag@endlink.
- *
- */
-#define CHECK_CP_TAG2(u2var, cptag1, cptag2) \
- if ((cptag1 != CP_TAG(pcfs, u2var)) && \
- (cptag2 != CP_TAG(pcfs, u2var))) \
- { \
- /* Somebody is confused */ \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_VERIFYERROR); \
-/*NOTREACHED*/ \
- }
-
-
-/*!
- * @brief Check that a constant_pool entry contains
- * the right kind of tag for this operation, from a choice of three.
- *
- *
- * @param u2var Name of a @link #u2 u2@endlink variable that
- * contains a constant_pool entry to be examined.
- *
- * @param cptag1 First constant_pool tag that is valid for this
- * operation.
- *
- * @param cptag2 Second constant_pool tag that is valid for this
- * operation.
- *
- * @param cptag3 Third constant_pool tag that is valid for this
- * operation.
- *
- *
- * @returns @link #rvoid rvoid@endlink
- *
- *
- * @throws JVMCLASS_JAVA_LANG_VERIFYERROR
- * @link #JVMCLASS_JAVA_LANG_VERIFYERROR
- if the constant_pool entry does not have the right tag@endlink.
- *
- */
-#define CHECK_CP_TAG3(u2var, cptag1, cptag2, cptag3) \
- if ((cptag1 != CP_TAG(pcfs, u2var)) && \
- (cptag2 != CP_TAG(pcfs, u2var)) && \
- (cptag3 != CP_TAG(pcfs, u2var))) \
- { \
- /* Somebody is confused */ \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_VERIFYERROR); \
-/*NOTREACHED*/ \
- }
-
-/*@} */ /* End of grouped definitions */
-
-/*!
- * @brief Force conversion of any Java type variable
- * of @c @b sizeof(jint) into a @link #jint jint@endlink
- * variable, but without conversion of contents.
- *
- *
- * This macro is typically used to move a
- * @link #jvm_object_hash jobject@endlink reference or a
- * @link #jfloat jfloat@endlink into a @link #jint jint@endlink
- * word, but suppress type conversion between the
- * source and destination variables. It derives the
- * address of the 32-bit source value, casts it as a
- * pointer to the destination data type, then extracts
- * that type.
- *
- * @warning This macro @e must have a 32-bit word as its source.
- * For use with smaller types, perform a widening conversion
- * first (such as @link #jboolean jboolean@endlink) to
- * @link #jint jint@endlink. Then and only then will
- * the target type work correctly.
- *
- * @warning Since this macro takes the address of its source parameter,
- * it will only work for variables, not for expressions!
- *
- *
- * @param var_sizeofjint Any 32-bit variable. If it is a smaller
- * type, such as (jboolean), perform a
- * widening conversion into (jint) first.
- *
- * @returns (jint) version of @b var_sizeofjint without conversion
- * of contents (such as jfloat-to-jint might want to do).
- *
- *
- * @todo A careful review of this macro across different compilers
- * is very much in order.
- *
- */
-#define FORCE_JINT(var_sizeofjint) \
- (*((jint *) ((jvoid *) &var_sizeofjint)))
-
-
-/*!
- * @brief Force conversion of any Java type variable
- * of @c @b sizeof(jint) into a @link #jfloat jfloat@endlink
- * variable, but without conversion of contents.
- *
- *
- * This macro is typically used to move a
- * @link #jint jint@endlink into a @link #jint jint@endlink
- * word, but suppress type conversion between the
- * source and destination variables.
- *
- * @warning For comments on the dangers of using this macro,
- * please refer to @link #FORCE_JINT() FORCE_JINT()@endlink.
- *
- *
- * @param var_sizeofjint Any 32-bit variable.
- *
- * @returns (jfloat) version of @b var_sizeofjint without conversion
- * of contents (such as jint-to-jfloat might want to do).
- *
- *
- * @todo A careful review of this macro across different compilers
- * is very much in order.
- *
- */
-#define FORCE_JFLOAT(var_sizeofjint) \
- (*((jfloat *) ((jvoid *) &var_sizeofjint)))
-
-
-/*!
- * @brief Calculate method_info pointer from program counter
- *
- * During the calculation, various scratch variables are
- * loaded and used to simplify the code. The final result
- * is a (method_info *) stored the local variable @b pmth
- *
- * @b Parameters: @link #rvoid rvoid@endlink
- *
- *
- * @returns @link #rvoid rvoid@endlink.
- *
- */
-#define CALCULATE_METHOD_INFO_FROM_PC \
- clsidxmisc = GET_PC_FIELD_IMMEDIATE(thridx, clsidx); \
- mthidxmisc = GET_PC_FIELD_IMMEDIATE(thridx, mthidx); \
- pcfsmisc = CLASS_OBJECT_LINKAGE(clsidxmisc)->pcfs; \
- pmth = METHOD(clsidxmisc, mthidxmisc)
-
-
-/*!
- * @brief Calculate ClassFile pointer from a class reference.
- *
- * During the calculation, various scratch variables are
- * loaded and used to simplify the code. Two final results
- * include a (CONSTANT_Class_info *) stored in the local variable
- * @b pcpd_Class stored the local variable @b pcfsmisc
- * and a (CONSTANT_Class_info *) stored in the local variable
- * @b pcpd_Class
- *
- * @param clsnameidx constant_pool index into class file of current
- * class (as indicated in the program counter)
- * that is a class reference entry.
- *
- *
- * @returns @link #rvoid rvoid@endlink.
- *
- *
- */
-#define CALCULATE_CLASS_INFO_FROM_CLASS_REFERENCE(clsnameidx) \
- pcpd = pcfs->constant_pool[clsnameidx]; \
- pcpd_Class = PTR_THIS_CP_Class(pcpd); \
- clsidxmisc = pcpd_Class->LOCAL_Class_binding.clsidxJVM; \
- if (jvm_class_index_null == clsidxmisc) \
- { \
- /* Need local variable to avoid possible expansion confusion */\
- jvm_constant_pool_index cpidxOLD = clsnameidx; \
- \
- /* If class is not loaded, go retrieve it by UTF8 class name */\
- LATE_CLASS_LOAD(cpidxOLD); \
- } \
- pcfsmisc = CLASS_OBJECT_LINKAGE(clsidxmisc)->pcfs; /* Extra ; */
-
-
-/*!
- * @brief Attempt to load a class that is not currently loaded.
- *
- *
- * @param clsnameidx CONSTANT_Utf8_info constant_pool index
- * to class name
- *
- * @return @link #rvoid rvoid@endlink
- *
- *
- * @throws JVMCLASS_JAVA_LANG_NOCLASSDEFFOUNDERROR
- * @link #JVMCLASS_JAVA_LANG_NOCLASSDEFFOUNDERROR
- if requested class cannot be located@endlink.
- *
- */
-#define LATE_CLASS_LOAD(clsnameidx) \
- \
- pcpd = pcfs->constant_pool[clsnameidx]; /* Class name */ \
- pcpd_Class = PTR_THIS_CP_Class(pcpd); \
- /* UTF8 string */ \
- pcpd = pcfs->constant_pool[pcpd_Class->name_index]; \
- pcpd_Utf8 = PTR_THIS_CP_Utf8(pcpd); \
- \
- prchar_clsname = utf_utf2prchar(pcpd_Utf8); \
- \
- /* Try again to load class */ \
- clsidxmisc = class_load_resolve_clinit(prchar_clsname, \
- CURRENT_THREAD, \
- rfalse, \
- rfalse); \
- \
- HEAP_FREE_DATA(prchar_clsname); \
- \
- /* If class is irretrievable, abort */ \
- if (jvm_class_index_null == clsidxmisc) \
- { \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_NOCLASSDEFFOUNDERROR); \
-/*NOTREACHED*/ \
- }
-
-
-
-
-/*!
- * @brief Calculate method_info pointer from a method reference.
- *
- * During the calculation, various scratch variables are
- * loaded and used to simplify the code. Two final results
- * include a (method_info *) stored the local variable @b pmth
- * and a (CONSTANT_Methodref_info *) stored in the local variable
- * @b pcpd_Methodref
- *
- * @param Methodref constant_pool index into class file of current
- * class (as indicated in the program counter) that
- * is a method reference entry.
- *
- *
- * @returns @link #rvoid rvoid@endlink.
- *
- *
- * @throws JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR
- * @link #JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR
- if requested method is not found in the class@endlink.
- *
- *
- */
-#define CALCULATE_METHOD_INFO_FROM_METHOD_REFERENCE(Methodref) \
- pcpd = pcfs->constant_pool[Methodref]; \
- pcpd_Methodref = PTR_THIS_CP_Methodref(pcpd); \
- clsidxmisc = pcpd_Methodref->LOCAL_Methodref_binding.clsidxJVM;\
- if (jvm_class_index_null == clsidxmisc) \
- { \
- /* If class is not loaded, go retrieve it by UTF8 class name */\
- LATE_CLASS_LOAD(pcpd_Methodref->class_index); \
- \
- /* Check if method exists in loaded class */ \
- clsidxmisc = pcpd_Methodref->LOCAL_Methodref_binding.clsidxJVM;\
- if (jvm_class_index_null == clsidxmisc) \
- { \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR); \
-/*NOTREACHED*/ \
- } \
- } \
- \
- mthidxmisc = pcpd_Methodref->LOCAL_Methodref_binding.mthidxJVM; \
- if (jvm_method_index_bad == mthidxmisc) \
- { \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR); \
-/*NOTREACHED*/ \
- } \
- \
- pcfsmisc = CLASS_OBJECT_LINKAGE(clsidxmisc)->pcfs; \
- pmth = pcfsmisc->methods[mthidxmisc]
-
-
-/*!
- * @brief Check for code attribute index in local method binding.
- *
- *
- * @param codeatridx Code attribute index from a local method binding
- *
- *
- * @return @link #rvoid rvoid@endlink
- *
- *
- * @throws JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR
- * @link #JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR
- if requested class static field is not found in the class@endlink.
- *
- */
-#define CHECK_VALID_CODEATRIDX(codeatridx) \
- if (jvm_attribute_index_bad == codeatridx) \
- { \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR); \
-/*NOTREACHED*/ \
- }
-
-
-/*!
- * @brief Check if this method is a static method.
- *
- *
- * @b Parameters: @link #rvoid rvoid@endlink
- *
- *
- * @return @link #rvoid rvoid@endlink
- *
- *
- * @throws JVMCLASS_JAVA_LANG_VERIFYERROR
- * @link #JVMCLASS_JAVA_LANG_VERIFYERROR
- if requested method is an object instance method@endlink.
- *
- */
-#define CHECK_STATIC_METHOD \
- \
- /* Must be a static method */ \
- if (!(ACC_STATIC & pmth->access_flags)) \
- { \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_VERIFYERROR); \
-/*NOTREACHED*/ \
- }
-
-
-/*!
- * @brief Check if this method is an object instance method.
- *
- *
- * @b Parameters: @link #rvoid rvoid@endlink
- *
- *
- * @return @link #rvoid rvoid@endlink
- *
- *
- * @throws JVMCLASS_JAVA_LANG_VERIFYERROR
- * @link #JVMCLASS_JAVA_LANG_VERIFYERROR
- if requested method is a static method@endlink.
- *
- */
-#define CHECK_INSTANCE_METHOD \
- \
- /* Must be an instance method */ \
- if (ACC_STATIC & pmth->access_flags) \
- { \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_VERIFYERROR); \
-/*NOTREACHED*/ \
- }
-
-
-#if 0
-/*!
- * @brief Check if this method is an @c @b abstract method,
- * that is, not having a concrete implementation.
- *
- *
- * @b Parameters: @link #rvoid rvoid@endlink
- *
- *
- * @return @link #rvoid rvoid@endlink
- *
- *
- * @throws JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
- * @link #JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
- if requested method is a method with a concrete implementatino@endlink.
- *
- */
-#define CHECK_ABSTRACT_METHOD \
- \
- /* Must not be a concrete method */ \
- if (!(ACC_ABSTRACT & pmth->access_flags)) \
- { \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
-\
-/* What exception gets thrown here? Need "not" of InstantiationError */\
-\
- JVMCLASS_JAVA_LANG_INSTANTIATIONERROR); \
-/*NOTREACHED*/ \
- }
-#endif
-
-
-/*!
- * @brief Check if this method is a concrete method, that is,
- * not @c @b abstract .
- *
- *
- * @b Parameters: @link #rvoid rvoid@endlink
- *
- *
- * @return @link #rvoid rvoid@endlink
- *
- *
- * @throws JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
- * @link #JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
- if requested method is an abstract method@endlink.
- *
- */
-#define CHECK_NOT_ABSTRACT_METHOD \
- \
- /* Must not be an abstract method */ \
- if (ACC_ABSTRACT & pmth->access_flags) \
- { \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_INSTANTIATIONERROR); \
-/*NOTREACHED*/ \
- }
-
-
-/*!
- * @brief Check if this object is from a concrete class, that is,
- * not from an @c @b abstract class.
- *
- *
- * @b Parameters: @link #rvoid rvoid@endlink
- *
- *
- * @return @link #rvoid rvoid@endlink
- *
- *
- * @throws JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
- * @link #JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
- if requested object is an abstract object@endlink.
- *
- */
-#define CHECK_NOT_ABSTRACT_CLASS \
- \
- /* Must not be from an abstract class */ \
- if (ACC_ABSTRACT & \
- OBJECT_CLASS_LINKAGE(objhashmisc)->pcfs->access_flags) \
- { \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_INSTANTIATIONERROR); \
-/*NOTREACHED*/ \
- }
-
-
-/*!
- * @brief Check if this object is a scalar, that is, not an array.
- *
- *
- * @b Parameters: @link #rvoid rvoid@endlink
- *
- *
- * @return @link #rvoid rvoid@endlink
- *
- *
- * @throws JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
- * @link #JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
- if requested method is an array object@endlink.
- *
- */
-#define CHECK_NOT_ARRAY_OBJECT \
- \
- /* Must not be an array object */ \
- if (OBJECT_STATUS_ARRAY & \
- CLASS(OBJECT_CLASS_LINKAGE(objhashmisc)->clsidx).status) \
- { \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_INSTANTIATIONERROR); \
-/*NOTREACHED*/ \
- }
-
-
-/*!
- * @brief Check if this object is from a normal class, that is,
- * not from an interface class.
- *
- *
- * @b Parameters: @link #rvoid rvoid@endlink
- *
- *
- * @return @link #rvoid rvoid@endlink
- *
- *
- * @throws JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
- * @link #JVMCLASS_JAVA_LANG_INSTANTIATIONERROR
- if requested object is from an interface class@endlink.
- *
- */
-#define CHECK_NOT_INTERFACE_CLASS \
- \
- /* Must not be from an interface class */ \
- if (ACC_INTERFACE & \
- OBJECT_CLASS_LINKAGE(objhashmisc)->pcfs->access_flags) \
- { \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_INSTANTIATIONERROR); \
-/*NOTREACHED*/ \
- }
-
-
-/*!
- * @brief Calculate field_info pointer from a field reference.
- *
- * During the calculation, various scratch variables are
- * loaded and used to simplify the code. Two final results
- * include a (field_info *) stored the local variable @b pfld
- * and a (CONSTANT_Fieldref_info *) stored in the local variable
- * @b pcpd_Fieldref
- *
- * @param Fieldref constant_pool index into class file of current
- * class (as indicated in the program counter) that
- * is a method reference entry.
- *
- *
- * @returns @link #rvoid rvoid@endlink.
- *
- *
- * @throws JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR
- * @link #JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR
- if requested field is not found in the class@endlink.
- *
- */
-#define CALCULATE_FIELD_INFO_FROM_FIELD_REFERENCE(Fieldref) \
- pcpd = pcfs->constant_pool[Fieldref]; \
- pcpd_Fieldref = PTR_THIS_CP_Fieldref(pcpd); \
- clsidxmisc = pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM; \
- if (jvm_class_index_null == clsidxmisc) \
- { \
- /* If class is not loaded, go retrieve it by UTF8 class name */\
- LATE_CLASS_LOAD(pcpd_Fieldref->class_index); \
- \
- /* Check if field exists in loaded class */ \
- clsidxmisc = pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM; \
- if (jvm_class_index_null == clsidxmisc) \
- { \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR); \
-/*NOTREACHED*/ \
- } \
- } \
- \
- fluidxmisc = pcpd_Fieldref->LOCAL_Fieldref_binding.fluidxJVM; \
- if (jvm_field_index_bad == fluidxmisc) \
- { \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR); \
-/*NOTREACHED*/ \
- } \
- \
- pcfsmisc = CLASS_OBJECT_LINKAGE(clsidxmisc)->pcfs; \
- fluidxmisc = pcpd_Fieldref->LOCAL_Fieldref_binding.fluidxJVM; \
- pfld = pcfsmisc \
- ->fields[CLASS(clsidxmisc) \
- .class_static_field_lookup[fluidxmisc]]
-
-
-/*!
- * @brief Check for field lookup index in local field binding.
- *
- *
- * @param fluidx Field lookup index from a local field binding
- *
- *
- * @return @link #rvoid rvoid@endlink
- *
- *
- * @throws JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR
- * @link #JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR
- if requested class static field is not found in the class@endlink.
- *
- */
-#define CHECK_VALID_FIELDLOOKUPIDX(fluidx) \
- if (jvm_field_lookup_index_bad == fluidx) \
- { \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_NOSUCHFIELDERROR); \
-/*NOTREACHED*/ \
- }
-
-
-/*!
- * @brief Check if this field is a static field.
- *
- *
- * @b Parameters: @link #rvoid rvoid@endlink
- *
- *
- * @return @link #rvoid rvoid@endlink
- *
- *
- * @throws JVMCLASS_JAVA_LANG_INCOMPATIBLECLASSCHANGEERROR
- * @link #JVMCLASS_JAVA_LANG_INCOMPATIBLECLASSCHANGEERROR
- if requested field is an object instance field@endlink.
- *
- */
-#define CHECK_STATIC_FIELD \
- \
- /* Must be a static field */ \
- if (!(ACC_STATIC & pfld->access_flags)) \
- { \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_INCOMPATIBLECLASSCHANGEERROR); \
-/*NOTREACHED*/ \
- }
-
-
-/*!
- * @brief Check if this field is an object instance field.
- *
- *
- * @b Parameters: @link #rvoid rvoid@endlink
- *
- *
- * @return @link #rvoid rvoid@endlink
- *
- *
- * @throws JVMCLASS_JAVA_LANG_INCOMPATIBLECLASSCHANGEERROR
- * @link #JVMCLASS_JAVA_LANG_INCOMPATIBLECLASSCHANGEERROR
- if requested method is a static field@endlink.
- *
- */
-#define CHECK_INSTANCE_FIELD \
- \
- /* Must be an instance field */ \
- if (ACC_STATIC & pfld->access_flags) \
- { \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_INCOMPATIBLECLASSCHANGEERROR); \
-/*NOTREACHED*/ \
- }
-
-
-/*!
- * @brief Check if this field is a final field in the current class.
- *
- *
- * Determine if a final field is in the current class. If so, fine,
- * but otherwise it is in a superclass. This is an error.
- *
- * @b Parameters: @link #rvoid rvoid@endlink
- *
- *
- * @return @link #rvoid rvoid@endlink
- *
- *
- * @throws JVMCLASS_JAVA_LANG_ILLEGALACCESSERROR
- * @link #JVMCLASS_JAVA_LANG_ILLEGALACCESSERROR
- if requested field is final, but in a superclass@endlink.
- *
- */
-#define CHECK_FINAL_FIELD_CURRENT_CLASS \
- \
- { \
- jvm_class_index clsidxTMP; \
- \
- GET_PC_FIELD(thridx, clsidxTMP, clsidx); \
- \
- /* A final field must _not_ be found in a superclass */ \
- if ((ACC_FINAL & pfld->access_flags) && \
- (clsidxTMP != pcpd_Fieldref \
- ->LOCAL_Fieldref_binding.clsidxJVM)) \
- { \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_ILLEGALACCESSERROR); \
-/*NOTREACHED*/ \
- } \
- }
-
-
-/*!
- * @brief Check if this field requires two @link #jint jint@endlink
- * accesses or just one.
- *
- *
- * JVM stack operations and local variable accesses need to know
- * if the datum to be moved takes one @link #jint jint@endlink slot
- * or two. Items of types @link #jlong jlong@endlink and
- * @link #jdouble jdouble@endlink take two such accesses, all others
- * take just one.
+ * \$Id$
*
- * @b Parameters: @link #rvoid rvoid@endlink
- *
- *
- * @returns @link #rtrue rtrue@endlink if this field takes two
- * accesses, otherwise @link #rfalse rfalse@endlink for smaller types.
- *
- */
-#define CHECK_TWO_ACCESSES \
- \
- (((pcpd_Fieldref->LOCAL_Fieldref_binding.jvaluetypeJVM == \
- BASETYPE_CHAR_J) || \
- (pcpd_Fieldref->LOCAL_Fieldref_binding.jvaluetypeJVM == \
- BASETYPE_CHAR_D)) \
- ? rtrue \
- : rfalse)
-
-
-/*!
- * @brief Store out value by data type into either class static field
- * or object instance field.
- *
- *
- * @param data_array Expression pointing to the class' or object's
- * @b XXX_data[] array, namely a (jvalue *).
- * Typically a fixed set of two expressions.
- *
- *
- * @returns @link #rvoid rvoid@endlink
- *
- *
- * @see PUTFIELD
- *
- * @see PUTSTATIC
- *
- *
- * @todo The various type casting games of integer/sub-integer
- * and integer/float/double and integer/objhash need to be
- * carefully scrutinized for correctness at run time.
- *
- * @todo Is BASTYPE_CHAR_ARRAY a legal case for @b PUTSTATIC and
- * @b PUTFIELD ?
- *
- */
-#define PUTDATA(data_array) \
- switch (pcpd_Fieldref->LOCAL_Fieldref_binding.jvaluetypeJVM) \
- { \
- case BASETYPE_CHAR_B: \
- POP(thridx, \
- data_array._jbyte, \
- jbyte); \
- break; \
- \
- case BASETYPE_CHAR_C: \
- POP(thridx, \
- data_array._jchar, \
- jchar); \
- break; \
- \
- case BASETYPE_CHAR_D: \
- /* \
- * DO NOT pop into a 64-bit word! @link #POP() POP@endlink\
- * was only designed to operate on 32-bit data types. \
- * Instead, use two instances. Besides, these halves \
- * needs to get pushed through bytegames_combine_jdouble() \
- * anyway to retrieve the final \
- * @link #jdouble jdouble@endlink value. \
- */ \
- POP(thridx, jitmp2, jint); \
- POP(thridx, jitmp1, jint); \
- data_array._jdouble = bytegames_combine_jdouble(jitmp1, \
- jitmp2); \
- break; \
- \
- case BASETYPE_CHAR_F: \
- /* \
- * DO NOT pop into a jfloat! This will consider \
- * the source as an integer to be converted instead \
- * of a 32-bit floating point word stored in a 32-bit \
- * integer word on the stack. Instead, use the \
- * FORCE_JFLOAT() macro to sustain contents across \
- * type boundaries. \
- */ \
- POP(thridx, jitmp1, jint); \
- data_array._jfloat = FORCE_JFLOAT(jitmp1); \
- break; \
- \
- case BASETYPE_CHAR_I: \
- POP(thridx, \
- data_array._jint, \
- /* redundant: */ jint); \
- break; \
- \
- case BASETYPE_CHAR_J: \
- /* \
- * DO NOT pop into a 64-bit word! @link #POP() POP@endlink\
- * was only designed to operate on 32-bit data types. \
- * Instead, use two instances. Besides, these halves \
- * needs to get pushed through bytegames_combine_jlong() \
- * anyway to retrieve the final \
- * @link #jlong jlong@endlink value. \
- */ \
- POP(thridx, jitmp2, jint); \
- POP(thridx, jitmp1, jint); \
- jltmp = bytegames_combine_jlong(jitmp1, jitmp2); \
- data_array._jlong = jltmp; \
- break; \
- \
- case BASETYPE_CHAR_L: \
- POP(thridx, \
- data_array._jobjhash, \
- jvm_object_hash); \
- break; \
- \
- case BASETYPE_CHAR_S: \
- POP(thridx, \
- data_array._jshort, \
- jshort); \
- break; \
- \
- case BASETYPE_CHAR_Z: \
- POP(thridx, \
- data_array._jboolean, \
- jboolean); \
- break; \
- \
- case BASETYPE_CHAR_ARRAY: \
- POP(thridx, \
- data_array._jarray, \
- jvm_object_hash); \
- break; \
- \
- case LOCAL_BASETYPE_ERROR: \
- default: \
- /* Something is @e very wrong if code gets here */ \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_VERIFYERROR); \
-/*NOTREACHED*/ \
- break; \
- }
-
-
-/*!
- * @brief Store out value by data type into class static field.
- *
- */
-#define PUTSTATIC \
- PUTDATA(CLASS(pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM) \
- .class_static_field_data[fluidxmisc])
-
-
-/*!
- * @brief Store out value by data type into object instance field.
- *
- */
-#define PUTFIELD \
- PUTDATA(OBJECT(pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM) \
- .object_instance_field_data[fluidxmisc])
-
-
-/*!
- * @brief Retrieve value by data type from either class static field or
- * object instance field.
- *
- *
- * @param data_array Expression pointing to the class' or object's
- * @b XXX_data[] array, namely a (jvalue *).
- * Typically a fixed set of two expressions.
- *
- *
- * @returns @link #rvoid rvoid@endlink
- *
- *
- * @see GETFIELD
- *
- * @see GETSTATIC
+ * Copyright 2005 The Apache Software Foundation
+ * or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 ("the License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied.
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
*
+ * @version \$LastChangedRevision$
*
- * @todo The various type casting games of integer/sub-integer
- * and integer/float/double and integer/objhash need to be
- * carefully scrutinized for correctness at run time.
+ * @date \$LastChangedDate$
*
- * @todo Is BASTYPE_CHAR_ARRAY a legal case for @b GETSTATIC and
- * @b GETFIELD ?
+ * @author \$LastChangedBy$
*
- */
-#define GETDATA(data_array) \
- switch (pcpd_Fieldref->LOCAL_Fieldref_binding.jvaluetypeJVM) \
- { \
- case BASETYPE_CHAR_B: \
- PUSH(thridx, \
- (jint) data_array._jbyte); \
- break; \
- \
- case BASETYPE_CHAR_C: \
- PUSH(thridx, \
- (jint) data_array._jchar); \
- break; \
- \
- case BASETYPE_CHAR_D: \
- bytegames_split_jdouble(data_array._jdouble, \
- &jitmp1, \
- &jitmp2); \
- /* \
- * DO NOT push from a 64-bit word! @link #PUSH() \
- PUSH@endlink was only designed to operate on 32-bit \
- * data types. Instead, use two instances. \
- */ \
- PUSH(thridx, jitmp1); \
- PUSH(thridx, jitmp2); \
- break; \
- \
- case BASETYPE_CHAR_F: \
- /* \
- * DO NOT pop into a jfloat! This will consider \
- * the source as an integer to be converted instead \
- * of a 32-bit floating point word stored in a 32-bit \
- * integer word on the stack. Instead, use the \
- * FORCE_JFLOAT() macro to sustain contents across \
- * type boundaries. \
- */ \
- jitmp1 = FORCE_JINT(data_array._jfloat); \
- PUSH(thridx, jitmp1); \
- break; \
- \
- case BASETYPE_CHAR_I: \
- PUSH(thridx, \
- (jint) /* ... redundant */ data_array._jint); \
- break; \
- \
- case BASETYPE_CHAR_J: \
- bytegames_split_jlong(data_array._jlong, \
- &jitmp1, \
- &jitmp2); \
- /* \
- * DO NOT push from a 64-bit word! @link #PUSH() \
- PUSH@endlink was only designed to operate on 32-bit \
- * data types. Instead, use two instances. \
- */ \
- PUSH(thridx, jitmp1); \
- PUSH(thridx, jitmp2); \
- break; \
- \
- case BASETYPE_CHAR_L: \
- PUSH(thridx, \
- (jint) data_array._jobjhash); \
- break; \
- \
- case BASETYPE_CHAR_S: \
- PUSH(thridx, \
- (jint) data_array._jshort); \
- break; \
- \
- case BASETYPE_CHAR_Z: \
- PUSH(thridx, \
- (jint) data_array._jboolean); \
- break; \
- \
- case BASETYPE_CHAR_ARRAY: \
- PUSH(thridx, \
- (jint) data_array._jarray); \
- break; \
- \
- case LOCAL_BASETYPE_ERROR: \
- default: \
- /* Something is @e very wrong if code gets here */ \
- thread_throw_exception(thridx, \
- THREAD_STATUS_THREW_ERROR, \
- JVMCLASS_JAVA_LANG_VERIFYERROR); \
-/*NOTREACHED*/ \
- break; \
- }
-
-
-/*!
- * @brief Retrieve value by data type from class static field.
+ * Original code contributed by Daniel Lydick on 09/28/2005.
*
- */
-#define GETSTATIC \
- GETDATA(CLASS(pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM) \
- .class_static_field_data[fluidxmisc])
-
-
-/*!
- * @brief Retrieve value by data type from object instance field.
+ * @section Reference
*
*/
-#define GETFIELD \
- GETDATA(OBJECT(pcpd_Fieldref->LOCAL_Fieldref_binding.clsidxJVM) \
- .object_instance_field_data[fluidxmisc])
+#include "arch.h"
+ARCH_SOURCE_COPYRIGHT_APACHE(opcode, c,
+"$URL$",
+"$Id$");
-/*@} */ /* End of grouped definitions */
-
-/*!
- * Handler linkage for end of thread detection.
- */
-static jmp_buf opcode_end_thread_return;
+#define PORTABLE_JMP_BUF_VISIBLE
+#include "jvmcfg.h"
+#include "cfmacros.h"
+#include "classfile.h"
+#include "exit.h"
+#include "gc.h"
+#include "jvm.h"
+#include "jvmclass.h"
+#include "linkage.h"
+#include "method.h"
+#include "native.h"
+#include "opcode.h"
+#include "opmacros.h"
+#include "utf.h"
+#include "util.h"
/*!
@@ -1294,7 +220,7 @@
* inner @c @b while() loop when a thread has finished
* running.
*
- * @b Parameters: @link #rvoid rvoid@endlink
+ * @param penv Non-local return buffer for use by @c @b setjmp(3) call.
*
*
* @returns From normal setup, integer
@@ -1304,18 +230,13 @@
* from @link #opcode_end_thread_test()
opcode_end_thread_test()@endlink.
*
+ * @attention See comments in @link jvm/src/portable_jmp_buf.c
+ portable_jmp_buf.c@endlink as to why this @e cannot
+ * be a function call.
+ *
*/
-static int opcode_end_thread_setup(rvoid)
-{
- /*
- * Return point from @c @b longjmp(3) as declared
- * in @link #opcode_end_thread_test()
- opcode_end_thread_test()@endlink
- */
- return(setjmp(opcode_end_thread_return));
-
-} /* END of opcode_end_thread_setup() */
+#define OPCODE_END_THREAD_SETUP(penv) PORTABLE_SETJMP(penv)
/*!
@@ -1335,18 +256,24 @@
* state and a non-local return exits the while loop.
*
*
- * @param thridx Thread index of thread to evaluate.
+ * @param thridx Thread index of thread to evaluate
+ *
+ * @param penv Non-local return buffer for use by @c @b longjmp(3)
+ * call.
*
*
* @returns @link #rvoid rvoid@endlink if end of thread test fails.
* If test passes, perform non-local state restoration from
- * setup via @c @b setjmp(3) as stored in @link
- #opcode_end_thread_return opcode_end_thread_return@endlink.
+ * setup via @c @b setjmp(3) as stored in a local variable
+ * in @link #opcode_run() opcode_run()@endlink.
*
*/
-static rvoid opcode_end_thread_test(jvm_thread_index thridx)
+static rvoid opcode_end_thread_test(jvm_thread_index thridx,
+ portable_jmp_buf *penv)
{
+ ARCH_FUNCTION_NAME(opcode_end_thread_test);
+
/* Check if thread has finished running */
/*!
@@ -1354,8 +281,8 @@
* something like a @c @b \<clinit\> or @c @b \<init\> was loaded
* on top of a running program.
*
- * @todo Should FP condition be fp_end_program <= THREAD().fp
- * instead of < condition?
+ * @todo HARMONY-6-jvm-opcode.c-2 Should FP condition be
+ * fp_end_program <= THREAD().fp instead of < condition?
*
*/
if (THREAD(thridx).fp_end_program < THREAD(thridx).fp)
@@ -1367,7 +294,9 @@
/* Thread has finished running, so return to @c @b setjmp(3) */
int rc = (int) EXIT_JVM_THREAD;
- longjmp(opcode_end_thread_return, rc);
+
+ PORTABLE_LONGJMP(penv, rc);
+
/*NOTREACHED*/
} /* END of opcode_end_thread_test() */
@@ -1401,45 +330,49 @@
* @link #JVMCLASS_JAVA_LANG_ERROR JVMCLASS_JAVA_LANG_ERROR@endlink.
* Anything else will produce undefined results.
*
- * @warning <b>This handler is not a simple as it seems!</b> You
- * absolutely @e must know what the non-local return mechanism
- * @c @b setjmp(3)/longjmp(3) is before attempting to figure it out!!!
- *
- * The strategy is a simple one: Trap thrown errors by this handler
- * and trap a failure in that error class by throwing a @link
- #JVMCLASS_JAVA_LANG_INTERNALERROR
- JVMCLASS_JAVA_LANG_INTERNALERROR@endlink. If that fails, give up.
- *
- * @b Details: When this function is first called due to a thrown
- * error, it attempts to load and run that error class. If all
- * is well, that class runs and everyone lives happily ever after.
- * If that class throws an error, however, this handler, having
- * been re-armed, is activated semi-recursively via @link
- #exit_throw_exception() exit_throw_exception()@endlink,
- * (that is, not entering at the top of function, but at the return
- * from @link #exit_throw_exception() exit_throw_exception()@endlink
- * with a non-zero return value), entering @e this code at
- * @link #exit_exception_setup exit_exception_setup()@endlink,
- * choosing the conditional branch != @link #EXIT_MAIN_OKAY
- EXIT_MAIN_OKAY@endlink and attempts to recursively load and
- * run @link #JVMCLASS_JAVA_LANG_LINKAGEERROR
- JVMCLASS_JAVA_LANG_LINKAGEERROR@endlink. If this is successful,
- * fine, call @link #exit_jvm() exit_jvm()@endlink and be done.
- * However, if even @e this fails and throws an error, the handler,
- * having been rearmed @e again by the attempt to invoke
- * @link #JVMCLASS_JAVA_LANG_LINKAGEERROR
- JVMCLASS_JAVA_LANG_LINKAGEERROR@endlink, it again semi-recursively
- * is activated via @link #exit_throw_exception()
- exit_throw_exception()@endlink and again enters the code at
- * @link #exit_exception_setup() exit_exception_setup()@endlink. This
- * time, the global
- * @link #opcode_calling_java_lang_linkageerror
- opcode_calling_java_lang_linkageerror@endlink is
- * @link #rtrue rtrue@endlink, so no more recursive invocations
- * are performed. Instead, @link #exit_jvm() exit_jvm()@endlink
- * with the most recent @link #EXIT_MAIN_OKAY EXIT_xxx@endlink code
- * from @link #exit_throw_exception() exit_throw_exception()@endlink
- * and be done.
+ * @warning <b><em>This handler is not a simple as it seems!</em></b>
+ * You absolutely @e must know what the non-local return
+ * mechanism @c @b setjmp(3)/longjmp(3) is before attempting
+ * to figure it out!!!
+ *
+ * The strategy is a simple one: Trap thrown errors by this
+ * handler and trap a failure in that error class by throwing
+ * a @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+ JVMCLASS_JAVA_LANG_INTERNALERROR@endlink. If that fails,
+ * give up.
+ *
+ * @b Details: When this function is first called due to a
+ * thrown error, it attempts to load and run that error class.
+ * If all is well, that class runs and everyone lives happily
+ * ever after. If that class throws an error, however, this
+ * handler, having been re-armed, is activated semi-recursively
+ * via @link #exit_throw_exception()
+ exit_throw_exception()@endlink, (that is, not entering at
+ * the top of function, but at the return from
+ * @link #exit_throw_exception() exit_throw_exception()@endlink
+ * with a non-zero return value), entering @e this code at
+ * @link #exit_exception_setup exit_exception_setup()@endlink,
+ * choosing the conditional branch != @link #EXIT_MAIN_OKAY
+ EXIT_MAIN_OKAY@endlink and attempts to recursively load and
+ * run @link #JVMCLASS_JAVA_LANG_LINKAGEERROR
+ JVMCLASS_JAVA_LANG_LINKAGEERROR@endlink. If this is
+ * successful, fine, call @link #exit_jvm() exit_jvm()@endlink
+ * and be done. However, if even @e this fails and throws an
+ * error, the handler, having been rearmed @e again by the
+ * attempt to invoke @link #JVMCLASS_JAVA_LANG_LINKAGEERROR
+ JVMCLASS_JAVA_LANG_LINKAGEERROR@endlink, it again
+ * semi-recursively is activated via
+ * @link #exit_throw_exception() exit_throw_exception()@endlink
+ * and again enters the code at @link #exit_exception_setup()
+ exit_exception_setup()@endlink. This time, the global
+ * @link #opcode_calling_java_lang_linkageerror
+ opcode_calling_java_lang_linkageerror@endlink is
+ * @link #rtrue rtrue@endlink, so no more recursive invocations
+ * are performed. Instead, @link #exit_jvm()
+ exit_jvm()@endlink with the most recent
+ * @link #EXIT_MAIN_OKAY EXIT_xxx@endlink code from
+ * @link #exit_throw_exception() exit_throw_exception()@endlink
+ * and be done.
*
*
* @param pThrowableEvent Null-terminated string name of
@@ -1450,42 +383,46 @@
* into.
*
*
- * @returns @link #rvoid rvoid@endlink. Either the
- * @c @b java.lang.Throwable class loads and
- * runs, or it loads @c @b java.lang.LinkageError
- * and runs it, then returns to caller, or it exits
- * due to an error somewhere in this sequence of
- * events.
+ * @returns @link #rvoid rvoid@endlink. Either the
+ * @c @b java.lang.Throwable class loads and
+ * runs, or it loads @c @b java.lang.LinkageError
+ * and runs it, then returns to caller, or it exits
+ * due to an error somewhere in this sequence of
+ * events.
*
*/
rvoid opcode_load_run_throwable(rchar *pThrowableEvent,
jvm_thread_index thridx)
{
+ ARCH_FUNCTION_NAME(opcode_load_run_throwable);
+
/******* Re-arm java.lang.LinkageError handler ***/
/*!
* @internal This call to exit_exception_setup() and the following
- * if (@link #EXIT_MAIN_OKAY EXIT_MAIN_OKAY@endlink) statement
- * constitute the ugly part of this code as described above.
- * See also other recursive calls and their control via
- * @link #opcode_calling_java_lang_linkageerror
- opcode_calling_java_lang_linkageerror@endlink:
+ * if (@link #EXIT_MAIN_OKAY EXIT_MAIN_OKAY@endlink)
+ * statement constitute the ugly part of this code as
+ * described above. See also other recursive calls and
+ * their control via @link
+ #opcode_calling_java_lang_linkageerror
+ opcode_calling_java_lang_linkageerror@endlink:
*
*/
- int nonlocal_rc = exit_exception_setup();
+ exit_exception_setup();
+ int nonlocal_rc = EXIT_EXCEPTION_SETUP();
if (EXIT_MAIN_OKAY != nonlocal_rc)
{
/*!
- * @todo Make this load and run the error class
- * @c @b \<clinit\> and default @c @b \<init\> method
- * instead of/in addition to fprintf(). Other
- * exit_throw_exception() handlers will have invoked
- * this method, so it @e must be rearmed @e again at
- * this point, lest an error that invokes it causes
- * an infinite loop.
+ * @todo HARMONY-6-jvm-opcode.c-3 Make this load and run
+ * the error class @c @b \<clinit\> and default
+ * @c @b \<init\> method instead of/in addition to
+ * fprintf(). Other exit_throw_exception() handlers
+ * will have invoked this method, so it @e must be
+ * rearmed @e again at this point, lest an error
+ * that invokes it causes an infinite loop.
*/
/* Should never be true via exit_throw_exception() */
@@ -1521,7 +458,7 @@
if (jvm_thread_index_null == thridx)
{
- sysErrMsg("opcode_load_run_throwable",
+ sysErrMsg(arch_function_name,
"Invalid thread index %d for throwable class %s",
thridx, pThrowableEvent);
return;
@@ -1542,16 +479,16 @@
/*!
* @internal Both mark (here) and unmark (below) class
- * so it gets garbage collected.
+ * so it gets garbage collected.
*/
(rvoid) GC_CLASS_MKREF_FROM_CLASS(jvm_class_index_null, clsidx);
/*!
* @internal Instantiate error class object and run its default
- * @c @b \<init\> method with default parameters.
+ * @c @b \<init\> method with default parameters.
*
- * If an error is thrown in objec_instance_new(), re-enter this
+ * If an error is thrown in object_instance_new(), re-enter this
* error function recursively at exit_exception_setup().
*/
jvm_object_hash objhash=
@@ -1565,14 +502,14 @@
/*!
* @internal Both mark and unmark object so it
- * gets garbage collected
+ * gets garbage collected
*/
(rvoid) GC_OBJECT_MKREF_FROM_OBJECT(jvm_object_hash_null, objhash);
(rvoid) GC_OBJECT_RMREF_FROM_OBJECT(jvm_object_hash_null, objhash);
/*!
* @internal Unmarked from above-- since JVM is going down,
- * this may be irrelevant, but be consistent.
+ * this may be irrelevant, but be consistent.
*/
(rvoid) GC_CLASS_RMREF_FROM_CLASS(jvm_class_index_null, clsidx);
@@ -1602,12 +539,14 @@
* may be found in object_run_method() as far as initiating execution
* of a JVM method.
*
- * @todo See if there is a better time-slicing algorithm that
- * is just as easy to use and keeps good real clock time.
+ * @todo HARMONY-6-jvm-opcode.c-4 See if there is a better
+ * time-slicing algorithm that is just as easy to use
+ * and keeps good real clock time.
*
- * @todo: having @c @b run_init_ (parm 7) for invocations of
- * opject_instance_new() to be @link #rfalse rfalse@endlink
- * the right thing to do for array initialization, namely
+ * @todo: HARMONY-6-jvm-opcode.c-5 having @c @b run_init_ (parm 6)
+ * for invocations of opject_instance_new() to be
+ * @link #rfalse rfalse@endlink the right thing to
+ * do for array initialization, namely
* opcodes @b NEWARRAY and @b ANEWARRAY ? Initializing an
* array is really not a constructor type
* of operation, but the individual components
@@ -1634,6 +573,18 @@
rboolean opcode_run(jvm_thread_index thridx,
rboolean check_timeslice)
{
+ ARCH_FUNCTION_NAME(opcode_run);
+
+ /*!
+ * @internal Handler linkage for end of thread detection.
+ * This structure is @e horrible. It is @e ugly. See
+ * @link jvm/src/portable_jmp_buf.c portable_jmp_buf.c@endlink
+ * for other hazards and rationale for workaround.
+ *
+ */
+ portable_jmp_buf opcode_end_thread_nonlocal_return;
+
+
/*
* Arm handler for the three conditions
* java.lang.Error, Exception, and Throwable.
@@ -1643,7 +594,7 @@
* handler in the class will issue:
*
* <b><code>
- longjmp(THREAD(thridx).nonlocal_ThrowableEvent, rc)
+PORTABLE_LONGJMP(THREAD(thridx).pportable_nonlocal_ThrowableEvent, rc)
</b></code>
*
* by way of @link #thread_throw_exception()
@@ -1659,7 +610,8 @@
int nonlocal_thread_return = EXIT_JVM_INTERNAL;
/* Calls @c @b setjmp(3) to arm handler */
- int nonlocal_rc = thread_exception_setup(thridx);
+ thread_exception_setup(thridx);
+ int nonlocal_rc = THREAD_EXCEPTION_SETUP(thridx);
/* Show error case first due to @e long switch() following */
if (THREAD_STATUS_EMPTY != nonlocal_rc)
@@ -1696,17 +648,23 @@
*/
if (THREAD_STATUS_THREW_EXCEPTION & nonlocal_rc)
{
- /*! @todo What needs to go here? */
+ /*!
+ * @todo HARMONY-6-jvm-opcode.c-6 What needs to go here?
+ */
}
else
if (THREAD_STATUS_THREW_ERROR & nonlocal_rc)
{
- /*! @todo What needs to go here? */
+ /*!
+ * @todo HARMONY-6-jvm-opcode.c-7 What needs to go here?
+ */
}
else
if (THREAD_STATUS_THREW_THROWABLE & nonlocal_rc)
{
- /*! @todo What needs to go here? */
+ /*!
+ * @todo HARMONY-6-jvm-opcode.c-8 What needs to go here?
+ */
}
else
if (THREAD_STATUS_THREW_UNCAUGHT & nonlocal_rc)
@@ -1723,7 +681,7 @@
if (jvm_class_index_null == clsidx)
{
/* Problem creating error class, so quit */
- sysErrMsg("opcode_run",
+ sysErrMsg(arch_function_name,
"Cannot find class %s",
JVMCLASS_JAVA_LANG_THREADGROUP);
@@ -1734,15 +692,17 @@
}
/*!
- * @todo Get @c @b ThreadGroup logic working that
- * figures out which @c @b java.lang.ThreadGroup
- * this thread is a part of and invoke
- * @c @b java.lang.ThreadGroup.uncaughtException()
- * for that specific object instead of this general method.
- * Probably the class library will gripe about not knowing
- * which object to associate with the method call since
- * @c @b java.lang.ThreadGroup.uncaughtException()
- * is @e not a @c @b static method.
+ * @todo HARMONY-6-jvm-opcode.c-9 Get @c @b ThreadGroup
+ * logic working that figures out which
+ * @c @b java.lang.ThreadGroup this thread is
+ * a part of and invoke
+ * @c @b java.lang.ThreadGroup.uncaughtException()
+ * for that specific object instead of this general
+ * method. Probably the class library will gripe
+ * about not knowing which object to associate with
+ * the method call since
+ * @c @b java.lang.ThreadGroup.uncaughtException()
+ * is @e not a @c @b static method.
*/
/*
@@ -1820,7 +780,7 @@
if (rfalse == opcode_run(thridx, rfalse))
{
/* Problem running error class, so quit */
- sysErrMsg("opcode_run",
+ sysErrMsg(arch_function_name,
"Cannot run exception method %s %s%s",
JVMCLASS_JAVA_LANG_THREADGROUP,
JVMCFG_UNCAUGHT_EXCEPTION_METHOD,
@@ -1844,7 +804,7 @@
/* Attempt to shut down thread due to condition */
if (rfalse == threadstate_request_complete(thridx))
{
- sysErrMsg("opcode_run",
+ sysErrMsg(arch_function_name,
"Unable to move completed thread %d to '%s' state",
thridx,
thread_state_get_name(THREAD_STATE_COMPLETE));
@@ -1858,7 +818,10 @@
} /* if THREAD_STATUS_THREW_UNCAUGHT */
else
{
- /*! @todo What needs to go here, if anything? */
+ /*!
+ * @todo HARMONY-6-jvm-opcode.c-10 What needs to go here,
+ * if anything?
+ */
}
/* Completely handled THREAD_STATUS_THREW_UNCAUGHT above */
@@ -1891,7 +854,7 @@
/* Attempt to shut down thread due to code completion */
if (rfalse == threadstate_request_complete(thridx))
{
- sysErrMsg("opcode_run",
+ sysErrMsg(arch_function_name,
"Unable to move aborted thread %d to '%s' state",
thridx,
thread_state_get_name(
@@ -1904,7 +867,7 @@
} /* if nonlocal_rc */
- } /* if thread_exception_setup() */
+ } /* if nonlocal_rc */
/***************************************************************/
/***************************************************************/
/***************************************************************/
@@ -1935,15 +898,26 @@
iswide = rfalse;
jvm_virtual_opcode opcode;
- u1 op1u1idx; /* Operand 1 as a (u1) CP index */
- u2 op1u2idx; /* Operand 1 as a (u2) CP index */
- u4 op1u4off; /* Operand 1 as a (u4) offset */
-
+ u1 op1u1; /* Operand 1 as a (u1) */
+ u2 op1u2; /* Operand 1 as a (u2) */
+ u4 op1u4; /* Operand 1 as a (u4) */
+ rboolean rbool1; /* Conditional instruction status */
+
+ jbyte jbtmp; /* Opcode (jbyte) scratch area */
+ jchar jctmp; /* Opcode (jchar) scratch area */
+ jshort jstmp; /* Opcode (jshort) scratch area */
jint jitmp1; /* Opcode (jint) scratch area 1 */
jint jitmp2; /* Opcode (jint) scratch area 2 */
- jlong jltmp; /* Opcode (jlong) scratch area */
- jfloat jftmp; /* Opcode (jfloat) scratch area */
- jdouble jdtmp; /* Opcode (jdouble) scratch area */
+ jint jitmp3; /* Opcode (jint) scratch area 3 */
+ jint jitmp4; /* Opcode (jint) scratch area 4 */
+ jlong jltmp1; /* Opcode (jlong) scratch area 1 */
+ jlong jltmp2; /* Opcode (jlong) scratch area 2 */
+ jfloat jftmp1; /* Opcode (jfloat) scratch area 1 */
+ jfloat jftmp2; /* Opcode (jfloat) scratch area 2 */
+ jdouble jdtmp1; /* Opcode (jdouble) scratch area 1*/
+ jdouble jdtmp2; /* Opcode (jdouble) scratch area 2*/
+ jvm_object_hash jotmp1; /* Opcode (jobject) scratch area 1*/
+ jvm_object_hash jotmp2; /* Opcode (jobject) scratch area 2*/
/* Scratch area for Fieldref and Methodref navigation */
@@ -1968,7 +942,9 @@
/* Calls @c @b setjmp(3) to arm handler */
- nonlocal_thread_return = opcode_end_thread_setup();
+
+ nonlocal_thread_return = OPCODE_END_THREAD_SETUP(
+ &opcode_end_thread_nonlocal_return);
/* Show error case first due to @e long switch() following */
if (EXIT_MAIN_OKAY != nonlocal_thread_return)
@@ -1980,7 +956,7 @@
/*!
* @internal For best runtime efficiency, place tests in
- * order of most to least frequent occurrence.
+ * order of most to least frequent occurrence.
*/
while ( /* This thread is in the RUNNING state */
@@ -1990,6 +966,15 @@
((rfalse == check_timeslice) || /* or if true and */
(rfalse == pjvm->timeslice_expired)))
{
+ sysDbgMsg(DMLNORM,
+ arch_function_name,
+ "PC=%04.4x %04.4x %04.4x %04.4x opcode=%02.2x",
+ pc->clsidx,
+ pc->mthidx,
+ pc->codeatridx,
+ pc->excpatridx,
+ pcode[pc->offset]);
+
/* Retrieve next virtual opcode */
opcode = pcode[pc->offset++];
@@ -2003,16 +988,12 @@
static void dummy1(void) { char *p, *dummy2; dummy2 = p; dummy1(); }
#define STUB { dummy1(); }
-sysDbgMsg(0, "opcode.c", "opcode = %x", opcode);
-
switch(opcode)
{
case OPCODE_00_NOP: /* Do nothing */
break;
case OPCODE_01_ACONST_NULL: /* Push NULL onto stack */
- /*! @todo Test this opcode */
- STUB;
PUSH(thridx, FORCE_JINT(jvm_object_hash_null));
break;
@@ -2028,11 +1009,9 @@
case OPCODE_09_LCONST_0:
case OPCODE_0A_LCONST_1:
- /*! @todo Test this opcode */
- STUB;
- jltmp = (((jlong) opcode) - ((jlong) OPCODE_09_LCONST_0));
+ jltmp1 = (((jlong) opcode) - ((jlong) OPCODE_09_LCONST_0));
- bytegames_split_jlong(jltmp, &jitmp1, &jitmp2);
+ bytegames_split_jlong(jltmp1, &jitmp1, &jitmp2);
PUSH(thridx, jitmp1); /* ms word */
PUSH(thridx, jitmp2); /* ls word */
@@ -2041,20 +1020,16 @@
case OPCODE_0B_FCONST_0:
case OPCODE_0C_FCONST_1:
case OPCODE_0D_FCONST_2:
- /*! @todo Test this opcode */
- STUB;
- jftmp = (jfloat) (((jint) opcode) - ((jint) OPCODE_0B_FCONST_0));
+ jftmp1 = (jfloat) (((jint) opcode) - ((jint) OPCODE_0B_FCONST_0));
- PUSH(thridx, FORCE_JINT(jftmp));
+ PUSH(thridx, FORCE_JINT(jftmp1));
break;
case OPCODE_0E_DCONST_0:
case OPCODE_0F_DCONST_1:
- /*! @todo Test this opcode */
- STUB;
- jdtmp = (jdouble) (((jint) opcode) - ((jint) OPCODE_0E_DCONST_0));
+ jdtmp1 = (jdouble) (((jint) opcode) - ((jint) OPCODE_0E_DCONST_0));
- bytegames_split_jdouble(jltmp, &jitmp1, &jitmp2);
+ bytegames_split_jdouble(jdtmp1, &jitmp1, &jitmp2);
PUSH(thridx, jitmp1); /* ms word */
PUSH(thridx, jitmp2); /* ls word */
@@ -2062,670 +1037,1196 @@
break;
case OPCODE_10_BIPUSH:
- /*! @todo Write this opcode */
- STUB;
+ GET_U1_OPERAND(op1u1);
+ jbtmp = (jbyte) op1u1; /* Play sign extension games */
+ jitmp1 = (jint) jbtmp;
+
+ PUSH(thridx, jitmp1);
break;
case OPCODE_11_SIPUSH:
- /*! @todo Write this opcode */
- STUB;
+ GET_U2_OPERAND(op1u2);
+ jstmp = (jshort) op1u2; /* Play sign extension games */
+ jitmp1 = (jint) jstmp;
+
+ PUSH(thridx, jitmp1);
break;
case OPCODE_12_LDC:
- /*! @todo Write this opcode */
+ /*! @todo HARMONY-6-jvm-opcode.c-11 Write this opcode */
STUB;
break;
case OPCODE_13_LDC_W:
- /*! @todo Write this opcode */
+ /*! @todo HARMONY-6-jvm-opcode.c-12 Write this opcode */
STUB;
break;
case OPCODE_14_LDC2_W:
- /*! @todo Write this opcode */
+ /*! @todo HARMONY-6-jvm-opcode.c-13 Write this opcode */
STUB;
break;
case OPCODE_15_ILOAD:
- /*! @todo Write this opcode */
- STUB;
- iswide = rfalse;
+ case_opcode_17_fload:
+ case_opcode_19_aload:
+
+ GET_WIDE_OR_NORMAL_INDEX(jitmp1, 0);
+
+ jitmp2 = GET_LOCAL_VAR(thridx, jitmp1);
+ PUSH(thridx, jitmp2);
break;
case OPCODE_16_LLOAD:
- /*! @todo Write this opcode */
- STUB;
- iswide = rfalse;
+ case_opcode_18_dload:
+
+ GET_WIDE_OR_NORMAL_INDEX(jitmp1, 1);
+
+ jitmp2 = GET_LOCAL_VAR(thridx, jitmp1);
+ jitmp3 = GET_LOCAL_VAR(thridx, jitmp1 + 1);
+ PUSH(thridx, jitmp2);
+ PUSH(thridx, jitmp3);
break;
case OPCODE_17_FLOAD:
- /*! @todo Write this opcode */
- STUB;
- iswide = rfalse;
- break;
+ /*!
+ * @internal Instead of treating (jfloat) as a (jint), both
+ * being 1 word, one could treat it separately, even
+ * though there is more code required to do it. This
+ * is more formally "correct" at the expense of code
+ * complexity, although probably not run time.
+ *
+ * <b><code>GET_WIDE_OR_NORMAL_INDEX(jitmp1, 0);</code></b>
+ *
+ * <b><code>jftmp1 = GET_LOCAL_VAR(thridx, jitmp1);</code></b>
+ *
+ * <b><code>PUSH(thridx, FORCE_JINT(jftmp1));</code></b>
+ *
+ * However, since all other types are simply moving
+ * (jint) words around, just follow suit in this case.
+ */
+
+ goto case_opcode_17_fload; /* Don't like 'goto', but makes sense */
case OPCODE_18_DLOAD:
- /*! @todo Write this opcode */
- STUB;
- iswide = rfalse;
- break;
+ goto case_opcode_18_dload; /* Don't like 'goto', but makes sense */
case OPCODE_19_ALOAD:
- /*! @todo Write this opcode */
- STUB;
- iswide = rfalse;
- break;
+ goto case_opcode_19_aload; /* Don't like 'goto', but makes sense */
case OPCODE_1A_ILOAD_0:
case OPCODE_1B_ILOAD_1:
case OPCODE_1C_ILOAD_2:
case OPCODE_1D_ILOAD_3:
- /*! @todo Write this opcode */
- STUB;
+
+ jitmp1 = (((jint) opcode) - ((jint) OPCODE_1A_ILOAD_0));
+
+ jitmp2 = GET_LOCAL_VAR(thridx, jitmp1);
+ PUSH(thridx, jitmp2);
break;
case OPCODE_1E_LLOAD_0:
case OPCODE_1F_LLOAD_1:
case OPCODE_20_LLOAD_2:
case OPCODE_21_LLOAD_3:
- /*! @todo Write this opcode */
- STUB;
+ jitmp1 = (((jint) opcode) - ((jint) OPCODE_1E_LLOAD_0));
+
+ jitmp2 = GET_LOCAL_VAR(thridx, jitmp1);
+ jitmp3 = GET_LOCAL_VAR(thridx, jitmp1 + 1);
+ PUSH(thridx, jitmp2);
+ PUSH(thridx, jitmp3);
break;
case OPCODE_22_FLOAD_0:
case OPCODE_23_FLOAD_1:
case OPCODE_24_FLOAD_2:
case OPCODE_25_FLOAD_3:
- /*! @todo Write this opcode */
- STUB;
+ jitmp1 = (((jint) opcode) - ((jint) OPCODE_22_FLOAD_0));
+
+ jitmp2 = GET_LOCAL_VAR(thridx, jitmp1);
+ PUSH(thridx, jitmp2);
break;
case OPCODE_26_DLOAD_0:
case OPCODE_27_DLOAD_1:
case OPCODE_28_DLOAD_2:
case OPCODE_29_DLOAD_3:
- /*! @todo Write this opcode */
- STUB;
+ jitmp1 = (((jint) opcode) - ((jint) OPCODE_26_DLOAD_0));
+
+ jitmp2 = GET_LOCAL_VAR(thridx, jitmp1);
+ jitmp3 = GET_LOCAL_VAR(thridx, jitmp1 + 1);
+ PUSH(thridx, jitmp2);
+ PUSH(thridx, jitmp3);
break;
case OPCODE_2A_ALOAD_0:
case OPCODE_2B_ALOAD_1:
case OPCODE_2C_ALOAD_2:
case OPCODE_2D_ALOAD_3:
- /*! @todo Write this opcode */
- STUB;
+ jitmp1 = (((jint) opcode) - ((jint) OPCODE_2A_ALOAD_0));
+
+ jitmp2 = GET_LOCAL_VAR(thridx, jitmp1);
+ PUSH(thridx, jitmp2);
break;
case OPCODE_2E_IALOAD:
- /*! @todo Write this opcode */
- STUB;
+ /*! @todo HARMONY-6-jvm-opcode.c-84 Needs unit testing with real data*/
+ POP(thridx, jitmp1, jint);
+ POP(thridx, jotmp1, jvm_object_hash);
+
+ VERIFY_OBJECT_HASH(jotmp1);
+ VERIFY_ARRAY_REFERENCE(jotmp1, BASETYPE_CHAR_I, jitmp1);
+
+ jitmp2 = ((jint *) OBJECT(jotmp1).arraydata)[jitmp1];
+ PUSH(thridx, jitmp2);
break;
case OPCODE_2F_LALOAD:
- /*! @todo Write this opcode */
- STUB;
+ /*! @todo HARMONY-6-jvm-opcode.c-85 Needs unit testing with real data*/
+ POP(thridx, jitmp1, jint);
+ POP(thridx, jotmp1, jvm_object_hash);
+
+ VERIFY_OBJECT_HASH(jotmp1);
+ VERIFY_ARRAY_REFERENCE(jotmp1, BASETYPE_CHAR_J, jitmp1);
+
+ jltmp1 = ((jlong *) OBJECT(jotmp1).arraydata)[jitmp1];
+
+ bytegames_split_jlong(jltmp1, &jitmp1, &jitmp2);
+ PUSH(thridx, jitmp1);
+ PUSH(thridx, jitmp2);
break;
case OPCODE_30_FALOAD:
- /*! @todo Write this opcode */
- STUB;
+ /*! @todo HARMONY-6-jvm-opcode.c-86 Needs unit testing with real data*/
+ POP(thridx, jitmp1, jint);
+ POP(thridx, jotmp1, jvm_object_hash);
+
+ VERIFY_OBJECT_HASH(jotmp1);
+ VERIFY_ARRAY_REFERENCE(jotmp1, BASETYPE_CHAR_F, jitmp1);
+
+ jftmp1 = ((jfloat *) OBJECT(jotmp1).arraydata)[jitmp1];
+ PUSH(thridx, FORCE_JINT(jftmp1));
break;
case OPCODE_31_DALOAD:
- /*! @todo Write this opcode */
- STUB;
+ /*! @todo HARMONY-6-jvm-opcode.c-87 Needs unit testing with real data*/
+ POP(thridx, jitmp1, jint);
+ POP(thridx, jotmp1, jvm_object_hash);
+
+ VERIFY_OBJECT_HASH(jotmp1);
+ VERIFY_ARRAY_REFERENCE(jotmp1, BASETYPE_CHAR_D, jitmp1);
+
+ jdtmp1 = ((jdouble *) OBJECT(jotmp1).arraydata)[jitmp1];
+
+ bytegames_split_jdouble(jdtmp1, &jitmp1, &jitmp2);
+ PUSH(thridx, jitmp1);
+ PUSH(thridx, jitmp2);
break;
case OPCODE_32_AALOAD:
- /*! @todo Write this opcode */
- STUB;
+ /*! @todo HARMONY-6-jvm-opcode.c-88 Needs unit testing with real data*/
+ POP(thridx, jitmp1, jint);
+ POP(thridx, jotmp1, jvm_object_hash);
+
+ VERIFY_OBJECT_HASH(jotmp1);
+ VERIFY_ARRAY_REFERENCE(jotmp1, BASETYPE_CHAR_L, jitmp1);
+
+ /*! @internal Careful! Use of 'jotmp1' as both rvalue and lvalue!*/
+ jotmp1 = ((jvm_object_hash *) OBJECT(jotmp1).arraydata)[jitmp1];
+ jitmp1 = (jint) jotmp1;
+ PUSH(thridx, jitmp1);
break;
case OPCODE_33_BALOAD:
- /*! @todo Write this opcode */
- STUB;
+ /*! @todo HARMONY-6-jvm-opcode.c-89 Needs unit testing with real data*/
+ POP(thridx, jitmp1, jint);
+ POP(thridx, jotmp1, jvm_object_hash);
+
+ VERIFY_OBJECT_HASH(jotmp1);
+ VERIFY_ARRAY_REFERENCE(jotmp1, BASETYPE_CHAR_B, jitmp1);
+
+ jbtmp = ((jbyte *) OBJECT(jotmp1).arraydata)[jitmp1];
+ jitmp2 = (jint) jbtmp; /* Play sign extension games */
+ PUSH(thridx, jitmp2);
break;
case OPCODE_34_CALOAD:
- /*! @todo Write this opcode */
- STUB;
+ /*! @todo HARMONY-6-jvm-opcode.c-90 Needs unit testing with real data*/
+ POP(thridx, jitmp1, jint);
+ POP(thridx, jotmp1, jvm_object_hash);
+
+ VERIFY_OBJECT_HASH(jotmp1);
+ VERIFY_ARRAY_REFERENCE(jotmp1, BASETYPE_CHAR_C, jitmp1);
+
+ jctmp = ((jchar *) OBJECT(jotmp1).arraydata)[jitmp1];
+ jitmp2 = (jint) jctmp; /* Play sign extension games */
+ PUSH(thridx, jitmp2);
break;
case OPCODE_35_SALOAD:
- /*! @todo Write this opcode */
- STUB;
+ /*! @todo HARMONY-6-jvm-opcode.c-91 Needs unit testing with real data*/
+ POP(thridx, jitmp1, jint);
+ POP(thridx, jotmp1, jvm_object_hash);
+
+ VERIFY_OBJECT_HASH(jotmp1);
+ VERIFY_ARRAY_REFERENCE(jotmp1, BASETYPE_CHAR_S, jitmp1);
+
+ jstmp = ((jshort *) OBJECT(jotmp1).arraydata)[jitmp1];
+ jitmp2 = (jint) jstmp; /* Play sign extension games */
+ PUSH(thridx, jitmp2);
break;
case OPCODE_36_ISTORE:
- /*! @todo Write this opcode */
- STUB;
- iswide = rfalse;
+ case_opcode_38_fstore:
+ case_opcode_3a_astore:
+
+ GET_WIDE_OR_NORMAL_INDEX(jitmp1, 0);
+
+ POP(thridx, jitmp2, jint);
+ PUT_LOCAL_VAR(thridx, jitmp1, jitmp2);
break;
case OPCODE_37_LSTORE:
- /*! @todo Write this opcode */
- STUB;
- iswide = rfalse;
+ case_opcode_39_lstore:
+
+ GET_WIDE_OR_NORMAL_INDEX(jitmp1, 1);
+
+ POP(thridx, jitmp3, jint);
+ POP(thridx, jitmp2, jint);
+ PUT_LOCAL_VAR(thridx, jitmp1, jitmp2);
+ PUT_LOCAL_VAR(thridx, jitmp1 + 1, jitmp3);
break;
case OPCODE_38_FSTORE:
- /*! @todo Write this opcode */
- STUB;
- iswide = rfalse;
- break;
+ goto case_opcode_38_fstore; /* Don't like 'goto', but makes sense */
case OPCODE_39_DSTORE:
- /*! @todo Write this opcode */
- STUB;
- iswide = rfalse;
- break;
+ goto case_opcode_39_lstore; /* Don't like 'goto', but makes sense */
case OPCODE_3A_ASTORE:
- /*! @todo Write this opcode */
- STUB;
- iswide = rfalse;
- break;
+ goto case_opcode_3a_astore; /* Don't like 'goto', but makes sense */
case OPCODE_3B_ISTORE_0:
case OPCODE_3C_ISTORE_1:
case OPCODE_3D_ISTORE_2:
case OPCODE_3E_ISTORE_3:
- /*! @todo Write this opcode */
- STUB;
+ jitmp1 = (((jint) opcode) - ((jint) OPCODE_3B_ISTORE_0));
+
+ POP(thridx, jitmp2, jint);
+ PUT_LOCAL_VAR(thridx, jitmp1, jitmp2);
break;
case OPCODE_3F_LSTORE_0:
case OPCODE_40_LSTORE_1:
case OPCODE_41_LSTORE_2:
case OPCODE_42_LSTORE_3:
- /*! @todo Write this opcode */
- STUB;
+ jitmp1 = (((jint) opcode) - ((jint) OPCODE_3F_LSTORE_0));
+
+ POP(thridx, jitmp3, jint);
+ POP(thridx, jitmp2, jint);
+ PUT_LOCAL_VAR(thridx, jitmp1 + 1, jitmp3);
+ PUT_LOCAL_VAR(thridx, jitmp1, jitmp2);
break;
case OPCODE_43_FSTORE_0:
case OPCODE_44_FSTORE_1:
case OPCODE_45_FSTORE_2:
case OPCODE_46_FSTORE_3:
- /*! @todo Write this opcode */
- STUB;
+ jitmp1 = (((jint) opcode) - ((jint) OPCODE_43_FSTORE_0));
+
+ POP(thridx, jitmp2, jint);
+ PUT_LOCAL_VAR(thridx, jitmp1, jitmp2);
break;
case OPCODE_47_DSTORE_0:
case OPCODE_48_DSTORE_1:
case OPCODE_49_DSTORE_2:
case OPCODE_4A_DSTORE_3:
- /*! @todo Write this opcode */
- STUB;
+ jitmp1 = (((jint) opcode) - ((jint) OPCODE_47_DSTORE_0));
+
+ POP(thridx, jitmp3, jint);
+ POP(thridx, jitmp2, jint);
+ PUT_LOCAL_VAR(thridx, jitmp1 + 1, jitmp3);
+ PUT_LOCAL_VAR(thridx, jitmp1, jitmp2);
break;
case OPCODE_4B_ASTORE_0:
case OPCODE_4C_ASTORE_1:
case OPCODE_4D_ASTORE_2:
case OPCODE_4E_ASTORE_3:
- /*! @todo Write this opcode */
- STUB;
+ jitmp1 = (((jint) opcode) - ((jint) OPCODE_4B_ASTORE_0));
+
+ POP(thridx, jitmp2, jint);
+ PUT_LOCAL_VAR(thridx, jitmp1, jitmp2);
break;
case OPCODE_4F_IASTORE:
- /*! @todo Write this opcode */
- STUB;
+ /*! @todo HARMONY-6-jvm-opcode.c-92 Needs unit testing with real data*/
+
+ POP(thridx, jitmp2, jint);
+ POP(thridx, jitmp1, jint);
+ POP(thridx, jotmp1, jvm_object_hash);
+
+ VERIFY_OBJECT_HASH(jotmp1);
+ VERIFY_ARRAY_REFERENCE(jotmp1, BASETYPE_CHAR_I, jitmp1);
+
+ ((jint *) OBJECT(jotmp1).arraydata)[jitmp1] = jitmp2;
break;
case OPCODE_50_LASTORE:
- /*! @todo Write this opcode */
- STUB;
+ /*! @todo HARMONY-6-jvm-opcode.c-93 Needs unit testing with real data*/
+
+ POP(thridx, jitmp3, jint);
+ POP(thridx, jitmp2, jint);
+ POP(thridx, jitmp1, jint);
+ POP(thridx, jotmp1, jvm_object_hash);
+
+ VERIFY_OBJECT_HASH(jotmp1);
+ VERIFY_ARRAY_REFERENCE(jotmp1, BASETYPE_CHAR_J, jitmp1);
+
+ jltmp1 = bytegames_combine_jlong(jitmp2, jitmp3);
+ ((jlong *) OBJECT(jotmp1).arraydata)[jitmp1] = jltmp1;
break;
case OPCODE_51_FASTORE:
- /*! @todo Write this opcode */
- STUB;
+ /*! @todo HARMONY-6-jvm-opcode.c-94 Needs unit testing with real data*/
+
+ POP(thridx, jitmp2, jint);
+ POP(thridx, jitmp1, jint);
+ POP(thridx, jotmp1, jvm_object_hash);
+
+ VERIFY_OBJECT_HASH(jotmp1);
+ VERIFY_ARRAY_REFERENCE(jotmp1, BASETYPE_CHAR_F, jitmp1);
+
+ jftmp1 = FORCE_JFLOAT(jitmp2);
+ ((jfloat *) OBJECT(jotmp1).arraydata)[jitmp1] = jftmp1;
break;
case OPCODE_52_DASTORE:
- /*! @todo Write this opcode */
- STUB;
+ /*! @todo HARMONY-6-jvm-opcode.c-95 Needs unit testing with real data*/
+
+ POP(thridx, jitmp3, jint);
+ POP(thridx, jitmp2, jint);
+ POP(thridx, jitmp1, jint);
+ POP(thridx, jotmp1, jvm_object_hash);
+
+ VERIFY_OBJECT_HASH(jotmp1);
+ VERIFY_ARRAY_REFERENCE(jotmp1, BASETYPE_CHAR_D, jitmp1);
+
+ jdtmp1 = bytegames_combine_jdouble(jitmp2, jitmp3);
+ ((jdouble *) OBJECT(jotmp1).arraydata)[jitmp1] = jdtmp1;
break;
case OPCODE_53_AASTORE:
- /*! @todo Write this opcode */
- STUB;
+ /*! @todo HARMONY-6-jvm-opcode.c-96 Needs unit testing with real data*/
+
+ POP(thridx, jitmp2, jint);
+ POP(thridx, jitmp1, jint);
+ POP(thridx, jotmp1, jvm_object_hash);
+
+ VERIFY_OBJECT_HASH(jotmp1);
+ VERIFY_ARRAY_REFERENCE(jotmp1, BASETYPE_CHAR_L, jitmp1);
+
+ ((jvm_object_hash *) OBJECT(jotmp1).arraydata)[jitmp1] = jitmp2;
break;
case OPCODE_54_BASTORE:
- /*! @todo Write this opcode */
- STUB;
[... 1569 lines stripped ...]