You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ge...@apache.org on 2005/10/08 06:29:29 UTC
svn commit: r307257 [7/24] - in
/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm: ./ bootJVM/
bootJVM/jni/ bootJVM/jni/src/ bootJVM/jni/src/gnu/
bootJVM/jni/src/gnu/classpath/ bootJVM/jni/src/gnu/classpath/0.16/
bootJVM/jni/src/gnu/classpath/...
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/attribute.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/attribute.h?rev=307257&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/attribute.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/attribute.h Fri Oct 7 21:27:56 2005
@@ -0,0 +1,75 @@
+#ifndef _attribute_h_included_
+#define _attribute_h_included_
+
+/*!
+ * @file attribute.h
+ *
+ * @brief Attribute management functions for the JVM.
+ *
+ *
+ * @section Control
+ *
+ * \$URL: https://svn.apache.org/path/name/attribute.h $ \$Id: attribute.h 0 09/28/2005 dlydick $
+ *
+ * Copyright 2005 The Apache Software Foundation
+ * or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 ("the License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied.
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * @version \$LastChangedRevision: 0 $
+ *
+ * @date \$LastChangedDate: 09/28/2005 $
+ *
+ * @author \$LastChangedBy: dlydick $
+ * Original code contributed by Daniel Lydick on 09/28/2005.
+ *
+ * @section Reference
+ *
+ */
+
+ARCH_COPYRIGHT_APACHE(attribute, h, "$URL: https://svn.apache.org/path/name/attribute.h $ $Id: attribute.h 0 09/28/2005 dlydick $");
+
+
+extern jvm_attribute_index attribute_find_in_field_by_cp_entry(
+ jvm_class_index clsidx,
+ jvm_field_index fldidx,
+ cp_info_dup *atrname);
+
+extern jvm_attribute_index attribute_find_in_field_by_enum(
+ jvm_class_index clsidx,
+ jvm_field_index fldidx,
+ rint atrenum);
+
+extern jvm_attribute_index attribute_find_in_method_by_cp_entry(
+ jvm_class_index clsidx,
+ jvm_method_index mthidx,
+ cp_info_dup *atrname);
+
+extern jvm_attribute_index attribute_find_in_method_by_enum(
+ jvm_class_index clsidx,
+ jvm_method_index mthidx,
+ rint atrenum);
+
+extern jvm_attribute_index attribute_find_in_class_by_cp_entry(
+ jvm_class_index clsidx,
+ cp_info_dup *atrname);
+
+extern jvm_attribute_index attribute_find_in_class_by_enum(
+ jvm_class_index clsidx,
+ rint atrenum);
+
+#endif /* _attribute_h_included_ */
+
+/* EOF */
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/bytegames.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/bytegames.c?rev=307257&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/bytegames.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/bytegames.c Fri Oct 7 21:27:56 2005
@@ -0,0 +1,838 @@
+/*!
+ * @file bytegames.c
+ *
+ * @brief Perform byte swapping, word swapping, byte-aligned accesses,
+ * non-aligned multi-byte items, etc.
+ *
+ * General utilities for playing shell games with real machine bytes
+ * for both the real machine and the Java virtual machine.
+ *
+ * Some machine architectures use little-endian versus big-endian byte
+ * ordering, some architectures do not natively support 2-byte or
+ * 4-byte or 8-byte word addressing on addesses that are not aligned
+ * to those boundaries. The JVM does not care about such things,
+ * but must accomodate real machine implementations in a way that
+ * they do not complain about it at run time. There area also
+ * functions here that provide such support. They typically are
+ * embedded in widely-used macros from
+ * @link jvm/src/cfmacros.h cfmacros.h@endlink and
+ * @link jvm/src/util.h util.h@endlink.
+ *
+ * @section Control
+ *
+ * \$URL: https://svn.apache.org/path/name/bytegames.c $ \$Id: bytegames.c 0 09/28/2005 dlydick $
+ *
+ * Copyright 2005 The Apache Software Foundation
+ * or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 ("the License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied.
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * @version \$LastChangedRevision: 0 $
+ *
+ * @date \$LastChangedDate: 09/28/2005 $
+ *
+ * @author \$LastChangedBy: dlydick $
+ * Original code contributed by Daniel Lydick on 09/28/2005.
+ *
+ * @section Reference
+ *
+ */
+
+#include "arch.h"
+ARCH_COPYRIGHT_APACHE(bytegames, c, "$URL: https://svn.apache.org/path/name/bytegames.c $ $Id: bytegames.c 0 09/28/2005 dlydick $");
+
+
+#include "jvmcfg.h"
+#include "util.h"
+
+/*!
+ * @name Unions for 1- 2- and 4- and 8-byte value ordering conversions.
+ *
+ * @brief Load in a value in one format and extract them in another.
+ *
+ * These unions are generic enough to be able to support signed and
+ * unsigned values for loading and storing 1-, 2-, 4-, and 8-byte
+ * integers.
+ *
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+/*!
+ * @brief Structure for shuffling two-byte values.
+ *
+ * Load into @b _usval as an rushort and extract as bytes,
+ * or vice versa.
+ *
+ */
+typedef union
+{
+ rushort _usval; /**< Unsigned short representation */
+
+ struct
+ {
+ rbyte a;
+ rbyte b;
+
+ } _byteval; /**< Unsigned byte representation */
+
+} twobyte;
+
+/*!
+ * @brief Structure for shuffling four-byte values
+ *
+ * Load into @b _ruival as an ruint or @b _juival as a juint
+ * and extract as bytes, or vice versa.
+ *
+ */
+typedef union
+{
+ ruint _ruival; /**< Real unsigned int representation */
+
+ juint _juival; /**< Java unsigned int representation */
+
+ struct
+ {
+ rbyte a;
+ rbyte b;
+ rbyte c;
+ rbyte d;
+
+ } _byteval; /**< Unsigned byte representation */
+
+} fourbyte;
+
+/*!
+ * @brief Structure for shuffling eight-byte values
+ *
+ * This structure handles both real types @link #rlong rlong@endlink
+ * @link #rdouble rdouble@endlink and Java types
+ * @link #jlong jlong@endlink and @link #jdouble jdouble@endlink
+ *
+ * Load into one of @b _rulval, @b _rdval, @b _julval, or @b _jdval,
+ * respectively, and extract as two unsigned integers from @b _intval
+ * or as bytes from @b _byteval. Any combination of loading and storing
+ * is permissible, although only certain combinations are useful for
+ * a given context. (Namely, storing as @link #jdouble jdouble@endlink
+ * and extracting as two @link #ruint ruint@endlink values doe not
+ * really make much sense.)
+ *
+ */
+typedef union
+{
+ rulong _rulval; /**< Real unsigned long long representation */
+
+ rdouble _rdval; /**< Real double representation */
+
+ rulong _julval; /**< Java unsigned long long representation */
+
+ rdouble _jdval; /**< Java double representation */
+
+ struct
+ {
+#ifdef ARCH_BIG_ENDIAN
+ fourbyte ms;
+ fourbyte ls;
+#else
+ fourbyte ls;
+ fourbyte ms;
+#endif
+
+ } _intval; /**< Unsigned int representation */
+
+ struct
+ {
+ rbyte a;
+ rbyte b;
+ rbyte c;
+ rbyte d;
+ rbyte e;
+ rbyte f;
+ rbyte g;
+ rbyte h;
+
+ } _byteval; /**< Unsigned byte representation */
+
+} eightbyte;
+
+/*@} */ /* End of grouped definitions */
+
+
+/**********************************************************************/
+/*!
+ * @name Unaligned multi-byte access support.
+ *
+ * @brief Store and retrieve arbitrary 2- and 4-byte values from
+ * unaligned addresses without causing @b SIGSEGV signals by performing
+ * 1-byte addressing on these locations.
+ *
+ * The 2- and 4-byte functions are typically used for absorbing class
+ * file stream data into a ClassFile structure. Of particular
+ * interest is
+ * @link #classfile_loadclassdata() classfile_loadclassdata()@endlink,
+ * where it is used to retrieve many different types of 2- and 4-byte
+ * data. The 8-byte functions are used by @link
+ #class_get_constant_field_attribute()
+ class_get_constant_field_attribute()@endlink for retrieving
+ * @link #jlong jlong@endlink and @link #jdouble jdouble@endlink
+ * constants.
+ *
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+/*!
+ * @brief Retrieve any generic 2-byte value (16 bits), whether or not
+ * its is aligned on a 2-byte (that is, even address) boundary.
+ *
+ * This function was written to suppress @b SIGSEGV issues on
+ * GCC -m32 binaries on a Solaris 9.
+ *
+ * Typical usage is in a situation of:
+ * @verbatim
+
+ rshort *pshort;
+ ...
+ val = *pshort; ... If pshort is at odd address, throw SIGSEGV.
+
+ @endverbatim
+ *
+ * Thus convert to:
+ * @verbatim
+
+ rshort *pshort;
+ ...
+ val = getrs2(pshort); ... No signal this way.
+
+ @endverbatim
+ *
+ * This causes two one-byte accesses to happen instead of a single
+ * two-byte access, eliminating the cause of @b SIGSEGV, unless, of
+ * course, the pointer is off in the weeds instead of looking at
+ * valid memory.
+ *
+ *
+ * @param ptr2 Pointer to @link #rushort rushort@endlink location.
+ *
+ *
+ * @returns 16-bit value at *ptr2, properly byte swapped.
+ *
+ */
+rushort bytegames_getrs2(rushort *ptr2)
+{
+ twobyte wholeval;
+
+ rbyte *ptr1 = (rbyte *) ptr2;
+
+ wholeval._byteval.a = *ptr1++;
+ wholeval._byteval.b = *ptr1;
+
+#ifdef ARCH_LITTLE_ENDIAN
+ wholeval._usval = swap2(wholeval._usval);
+#endif
+
+ return(wholeval._usval);
+
+} /* END of bytegames_getrs2() */
+
+
+/*!
+ * @brief Store any generic 2-byte value (16 bits), whether or not
+ * its is aligned on a 2-byte (that is, even address) boundary.
+ *
+ * This function is the inverse of
+ * @link #bytegames_getrs2() bytegames_getrs2()@endlink
+ * above, which see for further explanation.
+ *
+ *
+ * @param ptr2 Pointer to @link #rushort rushort@endlink location.
+ *
+ * @param val2 A @link #rushort rushort@endlink value to be stored.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ */
+rvoid bytegames_putrs2(rushort *ptr2, rushort val2)
+{
+ twobyte wholeval;
+
+ rbyte *ptr1 = (rbyte *) ptr2;
+
+ wholeval._usval = val2;
+
+#ifdef ARCH_LITTLE_ENDIAN
+ wholeval._usval = swap2(wholeval._usval);
+#endif
+
+ *ptr1++ = wholeval._byteval.a;
+ *ptr1 = wholeval._byteval.b;
+
+ return;
+
+} /* END of bytegames_putrs2() */
+
+
+/*!
+ * @brief 4-byte version of
+ * @link #bytegames_getrs2() bytegames_getrs2()@endlink, but
+ * performs two odd-byte accesses, not just one.
+ *
+ * This causes four one-byte accesses to happen instead of a single
+ * four-byte access, eliminating the cause of @b SIGSEGV.
+ *
+ * @param ptr4 Pointer to @link #ruint ruint@endlink location.
+ *
+ *
+ * @returns 32-bit value at *ptr4, properly byte swapped.
+ *
+ */
+ruint bytegames_getri4(ruint *ptr4)
+{
+ fourbyte wholeval;
+
+ rbyte *ptr1 = (rbyte *) ptr4;
+
+ wholeval._byteval.a = *ptr1++;
+ wholeval._byteval.b = *ptr1++;
+ wholeval._byteval.c = *ptr1++;
+ wholeval._byteval.d = *ptr1;
+
+#ifdef ARCH_LITTLE_ENDIAN
+ wholeval._ruival = swap4(wholeval._ruival);
+#endif
+
+ return(wholeval._ruival);
+
+} /* END of bytegames_getri4() */
+
+
+/*!
+ * @brief Store any generic 4-byte value (32 bits), whether or not
+ * its is aligned on a 2-byte (that is, even address) boundary.
+ *
+ * This function is the inverse of
+ * @link #bytegames_getri4() bytegames_getri4()@endlink
+ * above, which see for further explanation.
+ *
+ *
+ * @param ptr4 Pointer to @link #ruint ruint@endlink location.
+ *
+ * @param val4 An @link #ruint ruint@endlink value to be stored.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ */
+rvoid bytegames_putri4(ruint *ptr4, ruint val4)
+{
+ fourbyte wholeval;
+
+ rbyte *ptr1 = (rbyte *) ptr4;
+
+ wholeval._ruival = val4;
+
+#ifdef ARCH_LITTLE_ENDIAN
+ wholeval._ruival = swap4(wholeval._ruival);
+#endif
+
+ *ptr1++ = wholeval._byteval.a;
+ *ptr1++ = wholeval._byteval.b;
+ *ptr1++ = wholeval._byteval.c;
+ *ptr1 = wholeval._byteval.d;
+
+ return;
+
+} /* END of bytegames_putri4() */
+
+
+/*!
+ * @brief 8-byte version of
+ * @link #bytegames_getri4() bytegames_getri4()@endlink, but
+ * performs four odd-byte accesses, not just one.
+ *
+ * This causes eight one-byte accesses to happen instead of a single
+ * eight-byte access, eliminating the cause of @b SIGSEGV.
+ *
+ *
+ * @param ptr8 Pointer to @link #rulong rulong@endlink location.
+ *
+ *
+ * @returns 64-bit value from *ptr8, properly byte swapped.
+ *
+ */
+rulong bytegames_getrl8(rulong *ptr8)
+{
+ eightbyte wholeval;
+
+ rbyte *ptr1 = (rbyte *) ptr8;
+
+ wholeval._byteval.a = *ptr1++;
+ wholeval._byteval.b = *ptr1++;
+ wholeval._byteval.c = *ptr1++;
+ wholeval._byteval.d = *ptr1++;
+ wholeval._byteval.e = *ptr1++;
+ wholeval._byteval.f = *ptr1++;
+ wholeval._byteval.g = *ptr1++;
+ wholeval._byteval.h = *ptr1;
+
+#ifdef ARCH_LITTLE_ENDIAN
+ wholeval._rulval = bytegames_swap8(wholeval._rulval);
+#endif
+
+ return(wholeval._rulval);
+
+} /* END of bytegames_getrl8() */
+
+
+/*!
+ * @brief Store any generic 8-byte value (64 bits), whether or not
+ * its is aligned on a 2-byte (that is, even address) boundary.
+ *
+ * @brief This function is the inverse of
+ * @link #bytegames_getrl8() bytegames_getrl8()@endlink above, which see
+ * for further explanation.
+ *
+ * @attention NOTICE THAT THE TERM "long" and THE CAST @b (long) ARE
+ * FASTIDIOUSLY AVOIDED IN ORDER TO REMOVE ANY DOUBT AS
+ * TO WHAT IS A 32-BIT VALUE AND WHAT IS A 64-BIT VALUE!
+ *
+ *
+ * @param ptr8 Pointer to @link #rulong rulong@endlink location.
+ *
+ * @param val8 A @link #rulong rulong@endlink value to be stored.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ */
+rvoid bytegames_putrl8(rulong *ptr8, rulong val8)
+{
+ eightbyte wholeval;
+
+ rbyte *ptr1 = (rbyte *) ptr8;
+
+ wholeval._rulval = val8;
+
+#ifdef ARCH_LITTLE_ENDIAN
+ wholeval._rulval = bytegames_swap8(wholeval._rulval);
+#endif
+
+ *ptr1++ = wholeval._byteval.a;
+ *ptr1++ = wholeval._byteval.b;
+ *ptr1++ = wholeval._byteval.c;
+ *ptr1++ = wholeval._byteval.d;
+ *ptr1++ = wholeval._byteval.e;
+ *ptr1++ = wholeval._byteval.f;
+ *ptr1++ = wholeval._byteval.g;
+ *ptr1 = wholeval._byteval.h;
+
+ return;
+
+} /* END of bytegames_putrl8() */
+
+/*@} */ /* End of grouped definitions */
+
+
+/**********************************************************************/
+/*!
+ * @name Byte swapping support.
+ *
+ * @brief Swap 2- and 4- and 8-byte values, especially for support of
+ * little-endian real machines.
+ *
+ * Since the Java virtual machine is defined as a big-endian
+ * architecture, these functions are supplied to map between the
+ * big-endian JVM and a little-endian real machine implementation.
+ *
+ * The 2- and 4-byte functions are typically used for swapping class
+ * file stream data as it is being absorbed into a ClassFile structure,
+ * as well as for other general uses. Of particular interest is
+ * @link #classfile_loadclassdata() classfile_loadclassdata()@endlink,
+ * where they are used to swap many different types of 2- and 4-byte
+ * data. The 8-byte functions are provided for completeness.
+ *
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+/*!
+ * @brief Swap 2 bytes for a little-endian machine
+ * @link #rushort rushort@endlink value to a big-endian
+ * Java real machine implementation @link #rushort rushort@endlink
+ * value.
+ *
+ * Available but not used in big-endian architectures.
+ *
+ * This routine is mapped for little-endian machines to
+ * @link #MACHINE_JSHORT_SWAP MACHINE_JSHORT_SWAP()@endlink.
+ *
+ * @verbatim
+
+ INPUT BYTE ORDER: (a) (b) rshort: (ab)
+
+ OUTPUT BYTE ORDER: (b) (a) rshort: (ba)
+
+ @endverbatim
+ *
+ *
+ * @param val two-byte @link #rushort rushort@endlink to swap
+ *
+ *
+ * @returns swapped byte version of @b val
+ *
+ */
+rushort bytegames_swap2(rushort val)
+{
+ twobyte wholeval;
+
+ rbyte tmp;
+
+ wholeval._usval = val;
+
+ tmp = wholeval._byteval.a;
+ wholeval._byteval.a = wholeval._byteval.b;
+ wholeval._byteval.b = tmp;
+
+ return(wholeval._usval);
+
+} /* END of bytegames_swap2() */
+
+/*!
+ * @brief Swap 4 bytes for a little-endian machine
+ * @link #ruint ruint@endlink value to a big-endian
+ * Java real machine implementation
+ * @link #ruint ruint@endlink value.
+ *
+ * Available but not used in big-endian architectures.
+ *
+ * This routine is mapped for little-endian machines to
+ * @link #MACHINE_JINT_SWAP MACHINE_JINT_SWAP()@endlink.
+ *
+ * @verbatim
+
+ INPUT BYTE ORDER: (a) (b) (c) (d) rint: (abcd)
+
+ OUTPUT BYTE ORDER: (d) (c) (b) (a) rint: (dcba)
+
+ @endverbatim
+ *
+ *
+ * @param val four-byte @link #ruint ruint@endlink to swap
+ *
+ *
+ * @returns swapped byte version of @b val
+ *
+ */
+ruint bytegames_swap4(ruint val)
+{
+ fourbyte wholeval;
+
+ rbyte tmp;
+
+ wholeval._ruival = val;
+
+ tmp = wholeval._byteval.a;
+ wholeval._byteval.a = wholeval._byteval.d;
+ wholeval._byteval.d = tmp;
+
+ tmp = wholeval._byteval.b;
+ wholeval._byteval.b = wholeval._byteval.c;
+ wholeval._byteval.c = tmp;
+
+ return(wholeval._ruival);
+
+} /* END of bytegames_swap4() */
+
+
+/*!
+ * @brief Swap 8 bytes for a little-endian machine
+ * @link #rulong rulong@endlink value to a big-endian
+ * Java real machine implementation
+ * @link #rulong rulong@endlink value.
+ *
+ * Available but not used in big-endian architectures.
+ *
+ * This routine is mapped for little-endian machines to
+ * @link #MACHINE_JLONG_SWAP MACHINE_JLONG_SWAP()@endlink.
+ *
+ * @verbatim
+
+ INPUT BYTE ORDER: (a) (b) (c) (d) (e) (f) (g) (h) rlong: (abcdefgh)
+
+ OUTPUT BYTE ORDER: (h) (g) (f) (e) (d) (c) (b) (a) rlong: (hgfedcba)
+
+ @endverbatim
+ *
+ *
+ * @param val eight-byte @link #rulong rulong@endlink to swap
+ *
+ *
+ * @returns swapped byte version of @b val
+ *
+ */
+rulong bytegames_swap8(rulong val)
+{
+ eightbyte wholeval;
+
+ rbyte tmp;
+
+ wholeval._rulval = val;
+
+ tmp = wholeval._byteval.a;
+ wholeval._byteval.a = wholeval._byteval.h;
+ wholeval._byteval.h = tmp;
+
+ tmp = wholeval._byteval.b;
+ wholeval._byteval.b = wholeval._byteval.g;
+ wholeval._byteval.g = tmp;
+
+ tmp = wholeval._byteval.c;
+ wholeval._byteval.c = wholeval._byteval.f;
+ wholeval._byteval.f = tmp;
+
+ tmp = wholeval._byteval.d;
+ wholeval._byteval.d = wholeval._byteval.e;
+ wholeval._byteval.e = tmp;
+
+ return(wholeval._rulval);
+
+} /* END of bytegames_swap8() */
+
+
+/*!
+ * @brief Mix up 8 bytes for a little-endian machine
+ * @link #rushort rushort@endlink value to a big-endian
+ * Java real machine implementation
+ * @link #rushort rushort@endlink value in the same way as
+ * @link #bytegames_swap8() bytegames_swap8()@endlink,
+ * but store the words MS first, LS second.
+ *
+ * Available but not used in big-endian architectures.
+ *
+ * This routine is mapped for little-endian machines to
+ * @link #MACHINE_JLONG_MIX MACHINE_JLONG_MIX()@endlink.
+ *
+ * @verbatim
+
+ INPUT BYTE ORDER: (a) (b) (c) (d) (e) (f) (g) (h) rlong: (abcdefgh)
+
+ OUTPUT BYTE ORDER: (d) (c) (b) (a) (h) (g) (f) (e) rlong: (dcbahgfe)
+
+ @endverbatim
+ *
+ *
+ *
+ * @param val eight-byte @link #rulong rulong@endlink to swap/mix
+ *
+ * @returns swapped/mixed byte version of @b val
+ *
+ */
+rulong bytegames_mix8(rulong val)
+{
+ eightbyte wholeval;
+
+ rbyte tmp;
+
+ wholeval._rulval = val;
+
+ tmp = wholeval._byteval.a;
+ wholeval._byteval.a = wholeval._byteval.d;
+ wholeval._byteval.d = tmp;
+
+ tmp = wholeval._byteval.b;
+ wholeval._byteval.b = wholeval._byteval.c;
+ wholeval._byteval.c = tmp;
+
+ tmp = wholeval._byteval.e;
+ wholeval._byteval.e = wholeval._byteval.h;
+ wholeval._byteval.h = tmp;
+
+ tmp = wholeval._byteval.f;
+ wholeval._byteval.f = wholeval._byteval.e;
+ wholeval._byteval.e = tmp;
+
+ return(wholeval._rulval);
+
+} /* END of bytegames_mix8() */
+
+/*@} */ /* End of grouped definitions */
+
+
+/**********************************************************************/
+/*!
+ * @name Combine/split support for (jlong) and (jdouble).
+ *
+ * The @b combine operation takes two @link #jint jint@endlink words
+ * as the MS and LS words of a @link #jlong jlong@endlink or
+ * @link #jdouble jdouble@endlink and returns a combined result.
+ * This is typically used for retrieving JVM local variables or
+ * operand stack parameters.
+ *
+ * The @b split operation is the reverse. It takes a
+ * @link #jlong jlong@endlink or @link #jdouble jdouble@endlink and
+ * extracts two @link #jint jint@endlink words, typically for storage
+ * into a JVM local variable or operand stack parameter.
+ *
+ * @todo Verify that @e all references to these routines load and
+ * store the results in the proper order! The MS word @e must be stored
+ * first (local variable 'n' or first @link #PUSH() PUSH()@endlink
+ * to operand stack). The LS word @e must be stored second (local
+ * variable 'n+1' or second @link #PUSH() PUSH()@endlink to
+ * operand stack). The retrieval from the operand stack @e must
+ * be LS word as the first @link #POP() POP()@endlink, MS word
+ * as the second @link #POP() POP()@endlink operation. This
+ * problem may occur especially in
+ * @link jvm/src/native.c native.c@endlink and
+ * @link jvm/src/opcode.c opcode.c@endlink.
+ *
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+/*!
+ * @brief Combine two @link #jint jint@endlink words
+ * into a @link #jlong jlong@endlink.
+ *
+ * Pass in two sequential words as @link #jint jint@endlink from
+ * the JVM stack frame or operand stack or any other appropriate
+ * source and return a result as @link #jlong jlong@endlink
+ *
+ *
+ * @param msword Java integer at first index.
+ *
+ * @param lsword Java integer at second index, directly subsequent
+ * to @b msword.
+ *
+ * @returns concatenation as @link #jlong jlong@endlink, properly
+ * byte ordered.
+ */
+jlong bytegames_combine_jlong(jint msword, jint lsword)
+{
+ eightbyte wholeval;
+
+ wholeval._intval.ms._juival = msword;
+ wholeval._intval.ls._juival = lsword;
+
+ return(wholeval._julval);
+
+} /* END of bytegames_combine_jlong() */
+
+
+/*!
+ * @brief Combine two @link #jint jint@endlink words
+ * into a @link #jdouble jdouble@endlink
+ *
+ * Pass in two sequential words as @link #jint jint@endlink from the
+ * JVM stack frame or operand stack or any other appropriate source
+ * and return a result as @link #jdouble jdouble@endlink.
+ *
+ *
+ * @param msword Java integer at first index.
+ *
+ * @param lsword Java integer at second index, directly subsequent
+ * to @b msword.
+ *
+ * @returns concatenation as @link #jdouble jdouble@endlink ,
+ * properly byte ordered.
+ *
+ */
+jdouble bytegames_combine_jdouble(jint msword, jint lsword)
+{
+ eightbyte wholeval;
+
+ wholeval._intval.ms._juival = msword;
+ wholeval._intval.ls._juival = lsword;
+
+ return(wholeval._jdval);
+
+} /* END of bytegames_combine_jdouble() */
+
+
+/*!
+ * @brief Split a @link #jlong jlong@endlink into
+ * two @link #jint jint@endlink words.
+ *
+ * Pass in a @link #jlong jlong@endlink and return two words
+ * suitable for storing into a JVM stack frame as a pair of local
+ * variables or into the operand stack as two sequential
+ * words. The first receives the MS word, the second
+ * receives the LS word, which should be the next sequential
+ * stack frame local variable or operand stack location.
+ *
+ *
+ * @param[in] splitlong Java long integer to split.
+ *
+ * @param[out] msword Address of MS half of split value.
+ *
+ * @param[out] lsword Address of LS half of split value.
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ */
+rvoid bytegames_split_jlong(jlong splitlong, jint *msword, jint *lsword)
+{
+ eightbyte wholeval;
+
+ wholeval._julval = splitlong;
+
+ *msword = wholeval._intval.ms._juival;
+ *lsword = wholeval._intval.ls._juival;
+
+ return;
+
+} /* END of bytegames_split_jlong() */
+
+
+/*!
+ * @brief Split a @link #jdouble jdouble@endlink into
+ * two @link #jint jint@endlink words.
+ *
+ * Pass in a @link #jlong jlong@endlink and return two words
+ * suitable for storing into a JVM stack frame as a pair of local
+ * variables or into the operand stack as two sequential
+ * words. The first receives the MS word, the second
+ * receives the LS word, which should be the next sequential
+ * stack frame local variable or operand stack location.
+ *
+ *
+ * @param[in] splitdouble Java double float to split.
+ *
+ * @param[out] msword Address of MS half of split value.
+ *
+ * @param[out] lsword Address of LS half of split value.
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ */
+rvoid bytegames_split_jdouble(jdouble splitdouble,
+ jint *msword,
+ jint *lsword)
+{
+ eightbyte wholeval;
+
+ wholeval._jdval = splitdouble;
+
+ *msword = wholeval._intval.ms._juival;
+ *lsword = wholeval._intval.ls._juival;
+
+ return;
+
+} /* END of bytegames_split_jdouble() */
+
+/*@} */ /* End of grouped definitions */
+
+
+/* EOF */
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/cfattrib.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/cfattrib.c?rev=307257&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/cfattrib.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/cfattrib.c Fri Oct 7 21:27:56 2005
@@ -0,0 +1,825 @@
+/*!
+ * @file cfattrib.c
+ *
+ * @brief Implementation of <em>The Java Virtual Machine Specification,
+ * version 2, Chapter 4, the Class File Format</em>.
+ *
+ * This file contains the attribute manipulation functions. All
+ * other work is performed in
+ * @link jvm/src/classfile.c classfile.c@endlink.
+ *
+ *
+ * @section Control
+ *
+ * \$URL: https://svn.apache.org/path/name/cfattrib.c $ \$Id: cfattrib.c 0 09/28/2005 dlydick $
+ *
+ * Copyright 2005 The Apache Software Foundation
+ * or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 ("the License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied.
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * @version \$LastChangedRevision: 0 $
+ *
+ * @date \$LastChangedDate: 09/28/2005 $
+ *
+ * @author \$LastChangedBy: dlydick $
+ * Original code contributed by Daniel Lydick on 09/28/2005.
+ *
+ * @section Reference
+ *
+ */
+
+#include "arch.h"
+ARCH_COPYRIGHT_APACHE(cfattrib, c, "$URL: https://svn.apache.org/path/name/cfattrib.c $ $Id: cfattrib.c 0 09/28/2005 dlydick $");
+
+
+#include <string.h>
+
+#include "jvmcfg.h"
+#include "cfmacros.h"
+#include "classfile.h"
+#include "util.h"
+#include "utf.h"
+
+
+/*!
+ * @brief Convenient shorthand for attribute string comparison
+ *
+ *
+ * @param string Attribute string for comparison against ClassFile
+ * attribute_info value.
+ *
+ *
+ * @returns integer from utf_prchar_pcfs_strcmp()
+ *
+ */
+#define CMP_ATTRIBUTE(string) \
+ utf_prchar_pcfs_strcmp(string, pcfs, attribute_name_index)
+
+
+/*!
+ * @name Attribute test utilities.
+ *
+ *
+ * @param pcfs ClassFile structure containing
+ * attribute @b xxx.
+ *
+ * @param attribute_name_index Constant pool index of @b xxx
+ * attribute in this class file structure.
+ *
+ * @todo Both in this group of functions and probably numerous places
+ * around the code, the @link #u2 u2@endlink parameters that
+ * reference constant_pool entries should be changed to
+ * become type @link #jvm_constant_pool_index
+ jvm_constant_pool_index@endlink instead as a more accurate
+ * reflection of their purpose. This type was a later addition
+ * to the code and is therefore not reflected in the earlier
+ * portions that were written.
+ *
+ */
+
+
+/*@{ */ /* Begin grouped definitions */
+
+/*!
+ * @brief Map UTF8 string names for attributes in a constant_pool
+ * to LOCAL_xxx_ATTRIBUTE constants for the purpose of switch(int)
+ * instead of switch("string") code constructions.
+ *
+ *
+ * @returns enumeration constant from classfile_attribute_enum
+ *
+ */
+
+classfile_attribute_enum cfattrib_atr2enum(ClassFile *pcfs,
+ u2 attribute_name_index)
+{
+ if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_CONSTANTVALUE_ATTRIBUTE))
+ {
+ return(LOCAL_CONSTANTVALUE_ATTRIBUTE);
+ }
+ else
+ if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_CODE_ATTRIBUTE))
+ {
+ return(LOCAL_CODE_ATTRIBUTE);
+ }
+ else
+ if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_EXCEPTIONS_ATTRIBUTE))
+ {
+ return(LOCAL_EXCEPTIONS_ATTRIBUTE);
+ }
+ else
+ if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_INNERCLASSES_ATTRIBUTE))
+ {
+ return(LOCAL_INNERCLASSES_ATTRIBUTE);
+ }
+ else
+ if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_ENCLOSINGMETHOD_ATTRIBUTE))
+ {
+ return(LOCAL_ENCLOSINGMETHOD_ATTRIBUTE);
+ }
+ else
+ if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_SIGNATURE_ATTRIBUTE))
+ {
+ return(LOCAL_SIGNATURE_ATTRIBUTE);
+ }
+ else
+ if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_SYNTHETIC_ATTRIBUTE))
+ {
+ return(LOCAL_SYNTHETIC_ATTRIBUTE);
+ }
+ else
+ if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_SOURCEFILE_ATTRIBUTE))
+ {
+ return(LOCAL_SOURCEFILE_ATTRIBUTE);
+ }
+ else
+ if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_LINENUMBERTABLE_ATTRIBUTE))
+ {
+ return(LOCAL_LINENUMBERTABLE_ATTRIBUTE);
+ }
+ else
+ if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_LOCALVARIABLETABLE_ATTRIBUTE))
+ {
+ return(LOCAL_LOCALVARIABLETABLE_ATTRIBUTE);
+ }
+ else
+ if (0 ==
+ CMP_ATTRIBUTE(CONSTANT_UTF8_LOCALVARIABLETYPETABLE_ATTRIBUTE))
+ {
+ return(LOCAL_LOCALVARIABLETYPETABLE_ATTRIBUTE);
+ }
+ else
+ if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_DEPRECATED_ATTRIBUTE))
+ {
+ return(LOCAL_DEPRECATED_ATTRIBUTE);
+ }
+ else
+ if (0 == CMP_ATTRIBUTE(
+ CONSTANT_UTF8_RUNTIMEVISIBLEANNOTATIONS_ATTRIBUTE))
+ {
+ return(LOCAL_RUNTIMEVISIBLEANNOTATIONS_ATTRIBUTE);
+ }
+ else
+ if (0 == CMP_ATTRIBUTE(
+ CONSTANT_UTF8_RUNTIMEINVISIBLEANNOTATIONS_ATTRIBUTE))
+ {
+ return(LOCAL_RUNTIMEINVISIBLEANNOTATIONS_ATTRIBUTE);
+ }
+ else
+ if (0 == CMP_ATTRIBUTE(
+ CONSTANT_UTF8_RUNTIMEVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE))
+ {
+ return(LOCAL_RUNTIMEVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE);
+ }
+ else
+ if (0 == CMP_ATTRIBUTE(
+ CONSTANT_UTF8_RUNTIMEINVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE))
+ {
+ return(LOCAL_RUNTIMEINVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE);
+ }
+ else
+ if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_ANNOTATIONDEFAULT_ATTRIBUTE))
+ {
+ return(LOCAL_ANNOTATIONDEFAULT_ATTRIBUTE);
+ }
+ else
+ {
+ return(LOCAL_UNKNOWN_ATTRIBUTE);
+ }
+
+} /* END of cfattrib_atr2enum() */
+
+
+/*!
+ * @brief Short version of cfattrib_atr2enum(), but only check
+ * if an index refers to a Code_attribute area.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if this attribute is indeed
+ * a @link #CONSTANT_UTF8_CODE_ATTRIBUTE
+ CONSTANT_UTF8_CODE_ATTRIBUTE@endlink,
+ * otherwise @link #rfalse rfalse@endlink.
+ *
+ */
+rboolean cfattrib_iscodeattribute(ClassFile *pcfs,
+ u2 attribute_name_index)
+{
+ if (0 == CMP_ATTRIBUTE(CONSTANT_UTF8_CODE_ATTRIBUTE))
+ {
+ return(rtrue);
+ }
+ else
+ {
+ return(rfalse);
+ }
+} /* END of cfattrib_iscodeattribute() */
+
+/*@} */ /* End of grouped definitions */
+
+
+/*!
+ * @name Code_attribute deferencing support.
+ *
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+/*!
+ * @brief Conveniently reference the Code_attribute contained in
+ * an indirect <b><code>attribute_info_dup **dst</code></b>.
+ *
+ * After putting in the 4-byte access alignment changes,
+ * it became obvious that what was once (*dst)->member
+ * had become quite cumbersome. Therefore, in order to
+ * simplify access through (attribute_info_dup *)->ai.member
+ * constructions, including appropriate casting, the following
+ * macro is offered to take care of the most common usage.
+ * The few other references are unchanged, and the code is
+ * easier to understand.
+ *
+ * Notice that @link #DST_AI() DST_AI()@endlink references
+ * a <b><code>attribute_info_dup *dst</code></b>, while this
+ * macro references a <b><code>attribute_info_dup **dst</code></b>.
+ */
+#define PTR_DST_AI(dst) ((Code_attribute *) &(*dst)->ai)
+
+/*!
+ * @brief Conveniently reference the Code_attribute contained in
+ * a <b><code>attribute_info_dup *dst</code></b>, namely, with less
+ * pointer indirection.
+ *
+ * This is a counterpart for cfattrib_unloadattribute() where
+ * no indirection is needed. Notice that
+ * @link #PTR_DST_AI() PTR_DST_AI()@endlink references
+ * a <b><code>attribute_info_dup **dst</code></b>, while this
+ * macro references a <b><code>attribute_info_dup *dst</code></b>.
+ *
+ */
+#define DST_AI(dst) ((Code_attribute *) &dst->ai)
+
+/*@} */ /* End of grouped definitions */
+
+
+/*!
+ * @brief Load an attribute and verify that it has either valid contents
+ * or is ignored as an unknown attribute.
+ *
+ * If the attribute index is valid at all (for either a known or even
+ * an unknown but properly formed attribute), it will be copied
+ * into its destination area.
+ *
+ * @param pcfs Pointer to (partially) parsed ClassFile area
+ *
+ * @param dst Pointer to a attribute_info_dup[] address telling
+ * where in the heap this attribute will be
+ * copied from the source area.
+ *
+ * @param src Pointer to an attribute in class file image.
+ * This data will be stored in the heap at
+ * location @c @b *dst .
+ *
+ *
+ * @returns Point to first byte past this attribute,
+ * or @link #rnull rnull@endlink if parsing problem.
+ * If there is a problem, @b dst will contain a valid
+ * heap pointer only if there is a valid
+ * @link attribute_info.attribute_name_index
+ attribute_name_index@endlink, else it will also
+ * be @link #rnull rnull@endlink.
+ */
+
+u1 *cfattrib_loadattribute(ClassFile *pcfs,
+ attribute_info_dup **dst,
+ attribute_info *src)
+{
+ attribute_info tmpatr;
+ u4 tmplen;
+
+ jbyte *pnext_src = (jbyte *) src;
+
+ tmpatr.attribute_name_index = GETRS2(&src->attribute_name_index);
+ tmpatr.attribute_length = GETRI4(&src->attribute_length);
+
+ MACHINE_JSHORT_SWAP(tmpatr.attribute_name_index);
+ MACHINE_JINT_SWAP(tmpatr.attribute_length);
+
+ cfmsgs_typemsg("cfattrib_loadattribute",
+ pcfs,
+ tmpatr.attribute_name_index);
+ sysDbgMsg(DMLNORM,
+ "cfattrib_loadattribute",
+ "len=%d",
+ tmpatr.attribute_length);
+
+ /* Range check the name index (index is unsigned, so not checked) */
+ GENERIC_FAILURE_PTR(( /* (tmpatr.attribute_name_index < 0) || */
+ (tmpatr.attribute_name_index >=
+ pcfs->constant_pool_count)),
+ DMLNORM,
+ "loadClassFileStructures",
+ "attribute name index",
+ u1,
+ rnull,
+ rnull);
+
+ /* Calculate total size of this (attribute_info) area in src */
+ tmplen = sizeof(attribute_info)
+ - sizeof(u1)
+ + tmpatr.attribute_length;
+
+ /*
+ * Skip past this item's header and contents to next attribute,
+ * adjusting for dummy [info] field.
+ */
+ pnext_src += tmplen;
+
+
+ /* Calculate total size of this (attribute_info_dup) area in dst */
+ tmplen = sizeof(attribute_info_dup)
+ - sizeof(u1)
+ + tmpatr.attribute_length;
+
+ /* Allocate a heap location to store this attribute */
+ *dst = (attribute_info_dup *) HEAP_GET_METHOD(tmplen, rfalse);
+
+ /*
+ * Copy attribute data to heap. The @b info item is optional,
+ * depending on which attribute this is. Copy it in directly
+ * unless it is a Code_attribute, then do that specially.
+ * All other variable-length attributes have the @b SINGLE
+ * variable-length item at the END of the structure (except
+ * annotatons and local variable type attributes, which are being
+ * ignored by this implementation); therefore, there is no need
+ * to play pointer games to adjust what is stored where in those
+ * attributes. Simply index that array[] item.
+ *
+ * Also investigate attribute type constraints using a
+ * string-based @c @b switch .
+ */
+ (*dst)->empty[0] = FILL_INFO_DUP0;
+ (*dst)->empty[1] = FILL_INFO_DUP1;
+ (*dst)->ai.attribute_name_index = tmpatr.attribute_name_index;
+ (*dst)->ai.attribute_length = tmpatr.attribute_length;
+
+ classfile_attribute_enum atrenum =
+ cfattrib_atr2enum(pcfs, (*dst)->ai.attribute_name_index);
+
+ if (LOCAL_CODE_ATTRIBUTE == atrenum)
+ {
+ /*
+ * Copy Code_attribute field-by-field as in the top-level
+ * structure, allocating array[] pieces in that same manner.
+ *
+ * Note: You can get away with referencing
+ * @c @b src->member here because these first
+ * few members are of fixed length. You @e still must
+ * use GETRS2() or GETRI4() because they are in a
+ * byte-stream class file, which has no guaranteed
+ * word alignment.
+ */
+ PTR_DST_AI(dst)->max_stack =
+ GETRS2(&((Code_attribute *) src)->max_stack);
+
+ PTR_DST_AI(dst)->max_locals =
+ GETRS2(&((Code_attribute *) src)->max_locals);
+
+ PTR_DST_AI(dst)->code_length =
+ GETRI4(&((Code_attribute *) src)->code_length);
+
+ MACHINE_JSHORT_SWAP(*PTR_DST_AI(dst)->max_stack);
+ MACHINE_JSHORT_SWAP(*PTR_DST_AI(dst)->max_locals);
+ MACHINE_JINT_SWAP(*PTR_DST_AI(dst)->code_length);
+
+ if (0 == PTR_DST_AI(dst)->code_length)
+ {
+ /*
+ * Possible, but not theoretically reasonable,
+ * thus prohibited by spec
+ */
+ PTR_DST_AI(dst)->code = (u1 *) rnull;
+ }
+ else
+ {
+ PTR_DST_AI(dst)->code =
+ HEAP_GET_METHOD(PTR_DST_AI(dst)->code_length *
+ sizeof(u1),
+ rfalse);
+
+ /* Notice this is copy TO *ptr and FROM *bfr, not *ptr! */
+ memcpy( PTR_DST_AI(dst)->code,
+ /* 1st var len fld in class file code area */
+ &((Code_attribute *) src)->code,
+ (PTR_DST_AI(dst)->code_length) * sizeof(u1));
+
+ }
+
+ /*
+ * Load up variable fields now, use same technique as
+ * elsewhere.
+ *
+ */
+ jbyte *pabytes =(jbyte *) &((Code_attribute *) src)->code;
+ pabytes += PTR_DST_AI(dst)->code_length * sizeof(u1);
+
+ u2 *pu2;
+ MAKE_PU2(pu2, pabytes);
+
+ PTR_DST_AI(dst)->exception_table_length=GETRS2(pu2++);
+
+ pabytes = (u1 *) pu2;
+
+ if (0 == PTR_DST_AI(dst)->exception_table_length)
+ {
+ /* Possible, and theoretically reasonable */
+ PTR_DST_AI(dst)->exception_table = (rvoid *) rnull;
+ }
+ else
+ {
+ PTR_DST_AI(dst)->exception_table =
+ HEAP_GET_METHOD(PTR_DST_AI(dst)->exception_table_length *
+ sizeof(exception_table_entry),
+ rfalse);
+
+ memcpy(&PTR_DST_AI(dst)->exception_table,
+ pabytes,
+ (PTR_DST_AI(dst)->exception_table_length) *
+ sizeof(exception_table_entry));
+
+ pabytes += (PTR_DST_AI(dst)->exception_table_length) *
+ sizeof(exception_table_entry);
+ }
+
+ MAKE_PU2(pu2, pabytes);
+
+ PTR_DST_AI(dst)->attributes_count = GETRS2(pu2++);
+
+ pabytes = (jbyte *) pu2;
+
+ if (0 == PTR_DST_AI(dst)->attributes_count)
+ {
+ PTR_DST_AI(dst)->attributes =
+ (attribute_info_dup **) rnull;
+ }
+ else
+ {
+ PTR_DST_AI(dst)->attributes =
+ HEAP_GET_METHOD(PTR_DST_AI(dst)->attributes_count *
+ sizeof(attribute_info_dup *),
+ rtrue);
+
+
+ /*
+ * WARNING! RECURSIVE CALL:
+ *
+ * Load up each attribute in this attribute area.
+ * This should NOT recurse more than once since there
+ * can ONLY be ONE Code_attribute per method.
+ */
+
+ jvm_attribute_index atridx;
+
+ for (atridx = 0;
+ atridx < PTR_DST_AI(dst)->attributes_count;
+ atridx++)
+ {
+ /*
+ * Load an attribute and verify that it is either
+ * a valid (or an ignored) attribute, then point to
+ * next attribute in class file image.
+ */
+
+ pabytes =
+ cfattrib_loadattribute(
+ pcfs,
+ (attribute_info_dup **)
+ &(PTR_DST_AI(dst)->attributes)[atridx],
+ (attribute_info *) pabytes);
+
+ LOAD_SYSCALL_FAILURE_ATTRIB((rnull == pabytes),
+ "load field attribute",
+ *dst,
+ PTR_DST_AI(dst)->attributes);
+
+ } /* for (atridx) */
+ }
+
+ } /* if LOCAL_CODE_ATTRIBUTE */
+ else
+ {
+ /*
+ * See comments at top of @c @b if statment as to why
+ * all other structures can be directly copied into the heap
+ * area. The only other variable-length attributes are the
+ * annotation and local variable type attributes, which
+ * are being ignored by this implementation.
+ */
+ if (0 != tmpatr.attribute_length)
+ {
+ memcpy(&(*dst)->ai.info,
+ &src->info,
+ tmpatr.attribute_length);
+ }
+
+ } /* if LOCAL_CODE_ATTRIBUTE else */
+
+
+ /*! @todo Delete this when TODO: items below satisfied */
+ rboolean dummy = rtrue;
+
+ switch(atrenum)
+ {
+ case LOCAL_CONSTANTVALUE_ATTRIBUTE:
+
+ /*! @todo Verify "ConstantValue" attribute contents */
+ dummy = rfalse;
+
+ break;
+
+ case LOCAL_CODE_ATTRIBUTE:
+
+ /*! @todo Verify "Code" attribute contents */
+ dummy = rfalse;
+
+ break;
+
+ case LOCAL_EXCEPTIONS_ATTRIBUTE:
+
+ /*! @todo Verify "Exceptions" attribute contents */
+ dummy = rfalse;
+
+ break;
+
+ case LOCAL_INNERCLASSES_ATTRIBUTE:
+
+ /*! @todo Verify "InnerClasses" attribute contents */
+ dummy = rfalse;
+
+ break;
+
+ case LOCAL_ENCLOSINGMETHOD_ATTRIBUTE:
+
+ /*! @todo "EnclosingMethod" attribute has nothing to verify*/
+ dummy = rfalse;
+
+ break;
+
+ case LOCAL_SIGNATURE_ATTRIBUTE:
+
+ /*! @todo "Signature" attribute has nothing to verify */
+ dummy = rfalse;
+
+ break;
+
+ case LOCAL_SYNTHETIC_ATTRIBUTE:
+
+ /*! @todo "Synthetic" attribute has nothing to verify */
+ dummy = rfalse;
+
+ break;
+
+ case LOCAL_SOURCEFILE_ATTRIBUTE:
+
+ /*! @todo Verify "SourceFile" attribute contents */
+ dummy = rfalse;
+
+ break;
+
+ case LOCAL_LINENUMBERTABLE_ATTRIBUTE:
+
+ /*! @todo Verify "LineNumberTable" attribute contents */
+ dummy = rfalse;
+
+ break;
+
+ case LOCAL_LOCALVARIABLETABLE_ATTRIBUTE:
+
+ /*! @todo Verify "LocalVariableTable" attribute contents */
+ dummy = rfalse;
+
+ break;
+
+ case LOCAL_LOCALVARIABLETYPETABLE_ATTRIBUTE:
+
+ /*! @todo Verify "LocalVariableTypeTable" attribute
+ contents */
+ dummy = rfalse;
+
+ break;
+
+ case LOCAL_DEPRECATED_ATTRIBUTE:
+
+ /*! @todo "Deprecated" attribute has nothing to verify */
+ dummy = rfalse;
+
+ break;
+
+ case LOCAL_RUNTIMEVISIBLEANNOTATIONS_ATTRIBUTE:
+
+ /*! @todo Verify "RuntimeVisibleAnnotations" attribute
+ contents */
+ dummy = rfalse;
+
+ break;
+
+ case LOCAL_RUNTIMEINVISIBLEANNOTATIONS_ATTRIBUTE:
+
+ /*! @todo Verify "RuntimeInvisibleAnnotations" attribute
+ contents */
+ dummy = rfalse;
+
+ break;
+
+ case LOCAL_RUNTIMEVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE:
+
+ /*! @todo Verify "RuntimeVisibleParameterAnnotations"
+ contents */
+ dummy = rfalse;
+
+ break;
+
+ case LOCAL_RUNTIMEINVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE:
+
+ /*! @todo Verify "RuntimeInvisibleParameterAnnotations"
+ contents */
+ dummy = rfalse;
+
+ break;
+
+ case LOCAL_ANNOTATIONDEFAULT_ATTRIBUTE:
+
+ /*! @todo "AnnotationDefault" attribute has nothing to
+ verify */
+ dummy = rfalse;
+
+ break;
+
+ case LOCAL_UNKNOWN_ATTRIBUTE:
+ default:
+
+ /*!
+ * @todo Ignore unrecognized attribute.
+ * There really should not be anything
+ * to do here since the return value
+ * already points to the next attribute.
+ */
+ dummy = rfalse;
+
+ } /* switch(atrenum) */
+
+ return(pnext_src);
+
+} /* END of cfattrib_loadattribute() */
+
+
+/*!
+ * @brief UnLoad an attribute and free its heap area.
+ *
+ * @param pcfs Pointer to (partially) parsed ClassFile area
+ *
+ * @param dst Pointer to a attribute_info_dup allocation
+ * where this attribute is stored in the heap
+ *
+ * @returns @link #rvoid rvoid@endlink Whether it succeeds or fails,
+ * returning anything does not make much sense. This is
+ * similar to @c @b free(3) not returning anything even when
+ * a bad pointer was passed in.
+ *
+ */
+
+rvoid cfattrib_unloadattribute(ClassFile *pcfs,
+ attribute_info_dup *dst)
+{
+ /* Ignore any NULL pointers, nothing to do (should NEVER happen) */
+ if ((rnull == pcfs) || (rnull == dst))
+ {
+ return;
+ }
+
+ /*
+ * Free attribute data from the heap. The @b info item is optional,
+ * depending on which attribute this is. Free it directly
+ * unless it is a Code_attribute, then do that specially.
+ * All other variable-length attributes have the SINGLE variable
+ * length item at the END of the structure (except annotatons and
+ * local variable type attributes, which are being ignored by this
+ * implementation); therefore, there is no need to play pointer
+ * games to adjust what is stored where in those attributes.
+ * Simply index that array[] item and free it.
+ *
+ * Also investigate attribute type constraints using a
+ * string-based @c @b switch .
+ */
+
+ if (rtrue == cfattrib_iscodeattribute(pcfs,
+ DST_AI(dst)->attribute_name_index))
+
+ {
+ /*
+ * Free Code_attribute, all allocations in reverse order.
+ * (Should not make any difference, but this is how the
+ * constant_pool is being freed, so just do it the same
+ * way, namely, the reverse order in which allocations
+ * were made.)
+ */
+
+ if (0 == DST_AI(dst)->attributes_count)
+ {
+ /*
+ * Possible, and theoretically reasonable.
+ * Nothing to do here.
+ */
+ ;
+ }
+ else
+ {
+ /*
+ * WARNING! RECURSIVE CALL:
+ *
+ * Load up each attribute in this attribute area.
+ * This should NOT recurse more than once since there
+ * can ONLY be ONE Code_attribute per method.
+ */
+ jvm_attribute_index atridx;
+
+ for (atridx = 0;
+ atridx < DST_AI(dst)->attributes_count;
+ atridx++)
+ {
+ /*
+ * Unload an attribute
+ */
+
+ cfattrib_unloadattribute(pcfs,
+ DST_AI(dst)->attributes[atridx]);
+
+ } /* for (atridx) */
+
+ HEAP_FREE_METHOD(DST_AI(dst)->attributes);
+ }
+
+ if (0 == DST_AI(dst)->exception_table_length)
+ {
+ /*
+ * Possible, and theoretically reasonable.
+ * Nothing to do here.
+ */
+ ;
+ }
+ else
+ {
+ HEAP_FREE_METHOD(DST_AI(dst)->exception_table);
+ }
+
+ if (0 == DST_AI(dst)->code_length)
+ {
+ /*
+ * Possible, but not theoretically reasonable,
+ * thus prohibited by spec. Nothing to do here
+ * since @link Code_attribute#code code@endlink
+ * pointer is @link #rnull rnull@endlink.
+ */
+ ;
+ }
+ else
+ {
+ HEAP_FREE_METHOD(DST_AI(dst)->code);
+ }
+
+
+ /* Finally, free the main attribute area itself */
+ HEAP_FREE_METHOD(dst);
+
+ } /* if LOCAL_CODE_ATTRIBUTE */
+ else
+ {
+ /*
+ * See comments at top of @c @b if statment as to
+ * why all other structures can be directly freed from the
+ * heap area. The only other variable-length attributes are
+ * the annotation and local variable type attributes, which
+ * are being ignored by this implementation.
+ */
+ HEAP_FREE_METHOD(dst);
+
+ } /* if LOCAL_CODE_ATTRIBUTE else */
+
+
+ return;
+
+} /* END of cfattrib_unloadattribute() */
+
+
+/* EOF */
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/cfmacros.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/cfmacros.h?rev=307257&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/cfmacros.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/cfmacros.h Fri Oct 7 21:27:56 2005
@@ -0,0 +1,849 @@
+#ifndef _cfmacros_h_included_
+#define _cfmacros_h_included_
+
+/*!
+ * @file cfmacros.h
+ *
+ * @brief Macros for navigating class file structures in a ClassFile.
+ *
+ *
+ * @section Control
+ *
+ * \$URL: https://svn.apache.org/path/name/cfmacros.h $ \$Id: cfmacros.h 0 09/28/2005 dlydick $
+ *
+ * Copyright 2005 The Apache Software Foundation
+ * or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 ("the License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied.
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * @version \$LastChangedRevision: 0 $
+ *
+ * @date \$LastChangedDate: 09/28/2005 $
+ *
+ * @author \$LastChangedBy: dlydick $
+ * Original code contributed by Daniel Lydick on 09/28/2005.
+ *
+ * @section Reference
+ *
+ */
+
+ARCH_COPYRIGHT_APACHE(cfmacros, h, "$URL: https://svn.apache.org/path/name/cfmacros.h $ $Id: cfmacros.h 0 09/28/2005 dlydick $");
+
+#include "heap.h"
+
+/*!
+ * @name Typed constant_pool pointers
+ *
+ * @brief Convert generic constant_pool[] entry into a
+ * @link #CONSTANT_Class_info CONSTANT_xxxxx_info@endlink typed pointer,
+ * stripping off the generic prefix bytes.
+ *
+ * Adjust a generic constant_pool entry (cp_info_dup *)
+ * into its corresponding
+ * @link #CONSTANT_Class_info CONSTANT_xxxxx_info@endlink typed pointer
+ * by changing the pointer to point not to the beginning of the
+ * (cp_info_dup) structure, but to its @p @b cp member, which is where
+ * the data actually begins. This is useful for argument passing
+ * when the whole (cp_info_dup *) is available. The original
+ * adjustment was made in the first place to support native member
+ * accesses on real machine architectures that are picky about
+ * multi-byte accesses that are not aligned to addresses of the
+ * same size.
+ *
+ * @see ARCH_ODD4_ADDRESS_SIGSEGV
+ *
+ * @see ARCH_ODD2_ADDRESS_SIGSEGV
+ *
+ *
+ * @param pcpinfodup Pointer to a constant_pool entry, typically
+ * @c @b &pcfs->constant_pool[n]
+ *
+ *
+ * @returns Pointer to the @c @b ->cp member, typed as
+ * @link #CONSTANT_Class_info CONSTANT_xxxxx_info@endlink
+ *
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+#define PTR_THIS_CP_Class(pcpinfodup) \
+ ((CONSTANT_Class_info *) &(pcpinfodup)->cp)
+
+#define PTR_THIS_CP_Fieldref(pcpinfodup) \
+ ((CONSTANT_Fieldref_info *) &(pcpinfodup)->cp)
+
+#define PTR_THIS_CP_Methodref(pcpinfodup) \
+ ((CONSTANT_Methodref_info *) &(pcpinfodup)->cp)
+
+#define PTR_THIS_CP_InterfaceMethodref(pcpinfodup) \
+ ((CONSTANT_InterfaceMethodref_info *) &(pcpinfodup)->cp)
+
+#define PTR_THIS_CP_String(pcpinfodup) \
+ ((CONSTANT_String_info *) &(pcpinfodup)->cp)
+
+#define PTR_THIS_CP_Integer(pcpinfodup) \
+ ((CONSTANT_Integer_info *) &(pcpinfodup)->cp)
+
+#define PTR_THIS_CP_Float(pcpinfodup) \
+ ((CONSTANT_Float_info *) &(pcpinfodup)->cp)
+
+#define PTR_THIS_CP_Long(pcpinfodup) \
+ ((CONSTANT_Long_info *) &(pcpinfodup)->cp)
+
+#define PTR_THIS_CP_Double(pcpinfodup) \
+ ((CONSTANT_Double_info *) &(pcpinfodup)->cp)
+
+#define PTR_THIS_CP_NameAndType(pcpinfodup) \
+ ((CONSTANT_NameAndType_info *) &(pcpinfodup)->cp)
+
+#define PTR_THIS_CP_Utf8(pcpinfodup) \
+ ((CONSTANT_Utf8_info *) &(pcpinfodup)->cp)
+
+/*@} */ /* End of grouped definitions */
+
+
+/*!
+ * @name General navigation and parsing macros.
+ *
+ * @param pcfs ClassFile pointer to a fully parsed class data area
+ * @param cpidx Index into its constant_pool[] array.
+ *
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+/*!
+ * @brief Report the (cp_info *) of the address of the
+ * class file @p @b pcfs constant_pool entry at this
+ * index @p @b cpidx.
+ *
+ *
+ * @returns(cp_info *) to a constant_pool[cpidx]
+ *
+ */
+#define PTR_CP_ENTRY(pcfs, cpidx) (&(pcfs->constant_pool[cpidx])->cp)
+
+
+/*!
+ * @brief Report the (u1) tag value of the class file @p @b pcf
+ * constant_pool entry at this index @p @b cpidx.
+ *
+ *
+ * @returns (u1) tag value of entry at constant_pool[cpidx]
+ *
+ */
+#define CP_TAG(pcfs, cpidx) ((PTR_CP_ENTRY(pcfs, cpidx))->tag)
+
+
+/*!
+ * @brief Point into a (cp_info) data structure and return
+ * start of @link cp_info#info info@endlink field as a (u1 *).
+ *
+ *
+ * @returns address or contents of something in a constant_pool[] entry,
+ * see above description.
+ */
+#define PTR_CP_INFO(pcfs, cpidx) \
+ ((u1 *) (&PTR_CP_ENTRY(pcfs, cpidx)->info))
+
+/*@} */ /* End of grouped definitions */
+
+
+/*!
+ * @name Pointer casting for very common constructions.
+ *
+ * @brief Report the (cp_info *) of a PTR_CP_ENTRY(),
+ * but cast as a pointer to one of the following
+ * data types.
+ *
+ * The PTR_CP_ENTRY_TYPE() macro may used to choose any
+ * arbitrary type at all.
+ *
+ * If @p @b type is a
+ * (@link #CONSTANT_Class_info CONSTANT_xxxxx_info@endlink *), the
+ * result may be referenced DIRECTLY BY THE VM
+ * SPEC. These types are:
+ *
+ *
+ * <ul>
+ * <li>
+ * PTR_CP_ENTRY_TYPE() (any_desired_type *)
+ * </li>
+ *
+ * <li>
+ * PTR_CP_ENTRY_CLASS() (CONSTANT_Class_info *)
+ * </li>
+ *
+ * <li>
+ * PTR_CP_ENTRY_UTF8() (CONSTANT_Utf8_info *)
+ * </li>
+ * </ul>
+ *
+ *
+ * @param type typedef definition for pointer cast of result
+ *
+ * @param pcfs ClassFile pointer to a fully parsed class data area
+ *
+ * @param cpidx Index into its constant_pool[] array.
+ *
+ * @returns Pointer to a constant_pool[cpidx], variously typed as above.
+ *
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+#define PTR_CP_ENTRY_TYPE(type, pcfs, cpidx) \
+ ((type *) PTR_CP_ENTRY(pcfs, cpidx))
+
+#define PTR_CP_ENTRY_CLASS(pcfs, cpidx) \
+ ((CONSTANT_Class_info *) PTR_CP_ENTRY(pcfs, cpidx))
+
+#define PTR_CP_ENTRY_UTF8(pcfs, cpidx) \
+ ((CONSTANT_Utf8_info *) PTR_CP_ENTRY(pcfs, cpidx))
+
+/*@} */ /* End of grouped definitions */
+
+
+/*******************************************************************/
+/*!
+ * @name UTF string manipulation macros.
+ *
+ * @brief Probe CONSTANT_Utf8_info constant_pool entries for
+ * field data and addresses.
+ *
+ * Return information about (CONSTANT_Utf8_info) entry, namely:
+ *
+ * <ul>
+ *
+ * <li>
+ * Pointing to constant_pool entry of THIS @p @b pcfs and @p @b cpidx,
+ * being a (CONSTANT_Utf8_info) string:
+ * <ul>
+ * <li>
+ * PTR_CP_THIS() Pointer to whole (CONSTANT_Utf8_info)
+ * CP entry cast as (CONSTANT_Utf8_info *),
+ * namely to the beginning of the
+ * structure.
+ * </li>
+ *
+ * <li>
+ * CP_THIS_STRLEN() @p @b length field of
+ * (CONSTANT_Utf8_info) CP entry, as (u2).
+ * </li>
+ *
+ * <li>
+ * PTR_CP_THIS_STRNAME() Pointer to @p @b bytes area of
+ * (CONSTANT_Utf8_info) CP entry, cast
+ * as (rchar *).
+ * </li></ul></li>
+ *
+ *
+ * <li>
+ * ONE level of indirection, namely, point to UTF string info
+ * AT THE ENTRY POINTED TO by this @p @b pcfs and
+ * @p @b cpidx AS FOUND IN @p @b strname_idx FIELD:
+ * <ul>
+ *
+ * <li>
+ * PTR_CP1_NAME() Pointer to whole (CONSTANT_Utf8_info)
+ * CP entry referenced by index in
+ * @p @b strname_idx field, cast as
+ * (CONSTANT_Utf8_info *) and pointing
+ * to the beginning of that structure.
+ * </li>
+ *
+ * <li>
+ * CP1_NAME_STRLEN() @p @b length field of
+ * (CONSTANT_Utf8_info) field as
+ * indirectly referenced by
+ * PTR_CP1_NAME() macro, as (u2).
+ * </li>
+ *
+ * <li>
+ * PTR_CP1_NAME_STRNAME() Pointer to @p @b bytes area of
+ * (CONSTANT_Utf8_info) entry as
+ * indirectly referenced by
+ * PTR_CP1_NAME() macro, as (u1 *).
+ * </li></ul></li>
+ *
+ *
+ * <li>
+ * ONE level of indirection, specifically using type
+ * (CONSTANT_Class_info) as the constant_pool entry type.
+ *
+ * <ul>
+ *
+ * <li>
+ * PTR_CP1_CLASS_NAME() Pointer to whole (CONSTANT_Utf8_info)
+ * CP entry referenced by index that
+ * represents a (CONSTANT_Class_info)
+ * slot entry. Cast as type
+ * (CONSTANT_Utf8_info *) and pointing
+ * to the beginning of that structure.
+ * </li>
+ *
+ * <li>
+ * CP1_CLASS_NAME_STRLEN() @p @b length field of string name of this
+ * (CONSTANT_Class_info) entry's UTF
+ * name string, as (u2).
+ * </li>
+ *
+ * <li>
+ * PTR_CP1_CLASS_NAME_STRNAME() Pointer to @p @b bytes area of this
+ * (CONSTANT_Class_info) entry's UTF
+ * name string, as (u1 *).
+ * </li></ul></li>
+ *
+ * <li>
+ * TWO levels of indirection, namely, this @p @b pcfs and @p @b cpidx
+ * point to a (type) constant_pool entry whose
+ * @p @b strname_idx field contains a constant_pool
+ * index to a (CONSTANT_Class_info) entry.
+ * Obtain info about the (CONSTANT_Utf8_info)
+ * entry which is named by that (CONSTANT_Class_info)
+ * entry's @p @b name_index field, that is, the name
+ * of the class:
+ * <ul>
+ *
+ * <li>
+ * PTR_CP2_CLASS_NAME() Pointer to whole
+ * (CONSTANT_Utf8_info) CP entry
+ * referenced by index in
+ * @p @b strname_idx field of @b type
+ * CP entry (that is,
+ @link #CONSTANT_Class_info
+ CONSTANT_xxxxx_info@endlink),
+ * which references the class name
+ * of that CP entry, as referenced by
+ * the @p @b strname_idx CP entry of
+ * @p @b cpidx case as
+ * (CONSTANT_Utf8_info *) and
+ * pointing to the beginning of
+ * that structure.
+ * </li>
+ *
+ * <li>
+ * CP2_CLASS_NAME_STRLEN() @p @b length field of
+ * (CONSTANT_Utf8_info) field as
+ * indirectly referenced by
+ * PTR_CP2_CLASS_NAME() macro,
+ * as (u2).
+ * </li>
+ *
+ * <li>
+ * PTR_CP2_CLASS_NAME_STRNAME() Pointer to @p @b bytes area of
+ * (CONSTANT_Utf8_info) entry as
+ * indirectly referenced by
+ * PTR_CP2_CLASS_NAME() macro,
+ * as (u1 *).
+ * </li></ul></li></ul>
+ *
+ *
+ *
+ * @param type typedef definition for pointer cast of result
+ *
+ * @param pcfs ClassFile pointer to a fully parsed class
+ * data area
+ *
+ * @param cpidx Index into its constant_pool[] array.
+ *
+ * @param strname_idx Field name of indirect constant_pool pointed
+ * to by @p @b pcfs and @p @b cpidx. The index
+ * found here is the index containing the UTF
+ * string. (@b CP1_xxx and @b CP2_xxx macros only)
+ *
+ * @returns (cp_info *) to a constant_pool[cpidx]
+ *
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+/*******************************************************************
+ *
+ * Pointing to constant_pool entry of THIS @p @b pcfs and @p @b cpidx,
+ * being a (CONSTANT_Utf8_info) string.
+ *
+ */
+#define PTR_CP_THIS(pcfs, cpidx) \
+ PTR_CP_ENTRY_TYPE(CONSTANT_Utf8_info, pcfs, cpidx)
+
+#define CP_THIS_STRLEN(pcfs, cpidx) \
+ PTR_CP_ENTRY_TYPE(CONSTANT_Utf8_info, pcfs, cpidx)->length
+
+#define PTR_CP_THIS_STRNAME(pcfs, cpidx) \
+ ((rchar *) &PTR_CP_ENTRY_TYPE(CONSTANT_Utf8_info, pcfs, cpidx) \
+ ->bytes[0])
+
+
+/*******************************************************************
+ *
+ * --- ONE level of indirection, namely, point to UTF string info
+ * AT THE ENTRY POINTED TO by this @p @b pcfs and
+ * @p @b cpidx AS FOUND IN FIELD @p @b strname_idx:
+ */
+#define PTR_CP1_NAME(type, pcfs, cpidx, strname_idx) \
+ PTR_CP_THIS(pcfs, (PTR_CP_ENTRY_TYPE(type, pcfs,cpidx)->strname_idx))
+
+#define CP1_NAME_STRLEN(type, pcfs, cpidx, strname_idx) \
+ CP_THIS_STRLEN(pcfs, (PTR_CP_ENTRY_TYPE(type,pcfs,cpidx)->strname_idx))
+
+#define PTR_CP1_NAME_STRNAME(type, pcfs, cpidx, strname_idx) \
+ PTR_CP_THIS_STRNAME(pcfs, (PTR_CP_ENTRY_TYPE(type, pcfs, cpidx) \
+ ->strname_idx))
+
+/*******************************************************************
+ *
+ * --- ONE level of indirection, but specifically for manipulating
+ * (CONSTANT_Class_info) slot in constant_pool.
+ * @p @b pcfs and @b cpidx refer to such a class info
+ * slot.
+ */
+#define PTR_CP1_CLASS_NAME(pcfs, cpidx) \
+ PTR_CP1_NAME(CONSTANT_Class_info, pcfs, cpidx, name_index)
+
+
+#define CP1_CLASS_NAME_STRLEN(pcfs, cpidx) \
+ CP1_NAME_STRLEN(CONSTANT_Class_info, pcfs, cpidx, name_index)
+
+#define PTR_CP1_CLASS_NAME_STRNAME(pcfs, cpidx) \
+ PTR_CP1_NAME_STRNAME(CONSTANT_Class_info, pcfs, cpidx, name_index)
+
+/*******************************************************************
+ *
+ * --- TWO levels of indirection, namely, point to UTF string info
+ * AT THE ENTRY POINTED TO by this @p @b pcfs and
+ * @p @b cpidx AS FOUND IN FIELD @p @b strname_idx:
+ */
+
+#define PTR_CP2_CLASS_NAME(type, pcfs, cpidx, strname_idx) \
+ PTR_CP_THIS(pcfs, \
+ (PTR_CP_ENTRY_TYPE(CONSTANT_Class_info, \
+ pcfs, \
+ (PTR_CP_ENTRY_TYPE(type, pcfs, cpidx) \
+ ->strname_idx)) \
+ ->name_index))
+
+#define CP2_CLASS_NAME_STRLEN(type, pcfs, cpidx, strname_idx) \
+ CP_THIS_STRLEN(pcfs, \
+ (PTR_CP_ENTRY_TYPE(CONSTANT_Class_info, \
+ pcfs, \
+ (PTR_CP_ENTRY_TYPE(type, pcfs, cpidx) \
+ ->strname_idx)) \
+ ->name_index))
+
+#define PTR_CP2_CLASS_NAME_STRNAME(type, pcfs, cpidx, strname_idx) \
+ PTR_CP_THIS_STRNAME(pcfs, \
+ (PTR_CP_ENTRY_TYPE(CONSTANT_Class_info, \
+ pcfs, \
+ (PTR_CP_ENTRY_TYPE(type, pcfs, cpidx) \
+ ->strname_idx)) \
+ ->name_index))
+
+/*@} */ /* End of grouped definitions */
+
+/*******************************************************************/
+
+/*!
+ * @name Non-aligned multi-byte field access
+ *
+ * @brief Cast arbitrary pointers to type (u2 *) and (u4 *) for
+ * referencing items in class file data image. These pointers
+ * DO NOT need to be 2- or 4-byte aligned.
+ *
+ *
+ * @param ptr Name of pointer variable to receive (cast) value
+ *
+ * @param loc Name of pointer variable to be (recast) as either
+ * (u2 *) or (u4 *).
+ *
+ *
+ * @returns @p @b loc receives new value from (recast *) @p @b loc
+ *
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+#define MAKE_PU2(ptr, loc) ptr = (u2 *) (loc)
+#define MAKE_PU4(ptr, loc) ptr = (u4 *) (loc)
+
+/*@} */ /* End of grouped definitions */
+
+
+/*******************************************************************/
+/*!
+ * @name Responses to generic failure types
+ *
+ * @brief Generic return type for error test, including either return
+ * value of a typed @link #rnull rnull@endlink pointer
+ * (@b GENERIC_FAILUREx_PTR() only), a generic value
+ * (@b GENERIC_FAILUREx_VALUE() only), or throw an error
+ * (@b GENERIC_FAILUREx_THROWERROR() only), plus a error message.
+ * If @p @b expr is @link #rtrue rtrue@endlink, return the return value
+ * or throw the error (depending on the specific macro), else
+ * continue with inline code.
+ *
+ * The versions @b GENERAL_FAILURE1_xxx() and @b GENERAL_FAILURE2_xxx()
+ * also may pass a formatting parameter for @p @b msg to format into the
+ * output string.
+ *
+ * The following is a grand union of the parameters for @e all of these
+ * macros. A given macro may or may not use some of them:
+ *
+ *
+ * @param expr Any logical expression that returns
+ * @link #rtrue rtrue@endlink or
+ * @link #rfalse rfalse@endlink.
+ *
+ * @param dml Debug message level for amount of output verbosity
+ *
+ * @param fn Name of function invoking this macro
+ *
+ * @param msg Any text message to display to stderr if @p @b expr
+ * is @link #rtrue rtrue@endlink.
+ * For @b GENERIC_FAILURE{1|2}(), this
+ * should also contain 1 or 2 formatting items also.
+ *
+ * @param parm1 (for @b GENERIC_FAILURE{1|2}_xxx() only) First
+ * parameter to format into @p @b msg.
+ *
+ * @param parm2 (for @b GENERIC_FAILURE2_xxx() only) Second
+ * parameter to format into @p @b msg.
+ *
+ * @param rettype Function return TYPE (not including '*' modifier)
+ * to be used instead of (rvoid *). Used by
+ * @b GENERIC_FAILUREx_PTR() only.
+ *
+ * @param retval Function return VALUE, used by
+ * @b GENERIC_FAILUREx_VALUE() and
+ * @b GENERIC_FAILUREx_THROWERROR() .
+ *
+ * @param retclass Function error class to throw, used by
+ * GENERIC_FAILUREx_THROWERROR() only.
+ *
+ * @param heap1ptr Data heap block to free, or
+ * @link #rnull rnull@endlink if not needed.
+ *
+ * @param heap2ptr Data heap block to free, or
+ * @link #rnull rnull@endlink if not needed.
+ *
+ *
+ * @returns If @p @b expr is @link #rtrue rtrue@endlink,
+ * return a typed @link #rnull rnull@endlink pointer to the
+ * calling function, cast as <b><code>(rettype *)</code></b>,
+ * else continue with inline code.
+ *
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+#define GENERIC_FAILURE_PTR(expr, dml, fn, msg, rettype, \
+ heap1ptr, heap2ptr) \
+ if (expr) \
+ { \
+ HEAP_FREE_DATA((rvoid *) heap1ptr); /* Ignored if rnull */ \
+ HEAP_FREE_DATA((rvoid *) heap2ptr); /* Ignored if rnull */ \
+ sysDbgMsg(dml, fn, msg); \
+ return((rettype *) rnull); \
+ }
+
+#define GENERIC_FAILURE1_PTR(expr, dml, fn, msg, parm1, rettype, \
+ heap1ptr, heap2ptr) \
+ if (expr) \
+ { \
+ HEAP_FREE_DATA((rvoid *) heap1ptr); /* Ignored if rnull */ \
+ HEAP_FREE_DATA((rvoid *) heap2ptr); /* Ignored if rnull */ \
+ sysDbgMsg(dml, fn, msg, parm1); \
+ return((rettype *) rnull); \
+ }
+
+#define GENERIC_FAILURE2_PTR(expr, dml, fn, msg, parm1, parm2, rettype,\
+ heap1ptr, heap2ptr) \
+ if (expr) \
+ { \
+ HEAP_FREE_DATA((rvoid *) heap1ptr); /* Ignored if rnull */ \
+ HEAP_FREE_DATA((rvoid *) heap2ptr); /* Ignored if rnull */ \
+ sysDbgMsg(dml, fn, msg, parm1, parm2); \
+ return((rettype *) rnull); \
+ }
+
+#define GENERIC_FAILURE_VALUE(expr, dml, fn, msg, retval, heap1ptr, \
+ heap2ptr) \
+ if (expr) \
+ { \
+ HEAP_FREE_DATA((rvoid *) heap1ptr); /* Ignored if rnull */ \
+ HEAP_FREE_DATA((rvoid *) heap2ptr); /* Ignored if rnull */ \
+ sysDbgMsg(dml, fn, msg); \
+ return(retval); \
+ }
+
+#define GENERIC_FAILURE1_VALUE(expr, dml, fn, msg, parm1, retval, \
+ heap1ptr, heap2ptr) \
+ if (expr) \
+ { \
+ HEAP_FREE_DATA((rvoid *) heap1ptr); /* Ignored if rnull */ \
+ HEAP_FREE_DATA((rvoid *) heap2ptr); /* Ignored if rnull */ \
+ sysDbgMsg(dml, fn, msg, parm1); \
+ return(retval); \
+ }
+
+#define GENERIC_FAILURE2_VALUE(expr, dml, fn, msg, parm1, parm2,retval,\
+ heap1ptr, heap2ptr) \
+ if (expr) \
+ { \
+ HEAP_FREE_DATA((rvoid *) heap1ptr); /* Ignored if rnull */ \
+ HEAP_FREE_DATA((rvoid *) heap2ptr); /* Ignored if rnull */ \
+ sysDbgMsg(dml, fn, msg, parm1, parm2); \
+ return(retval); \
+ }
+
+#define GENERIC_FAILURE_THROWERROR(expr, dml, fn, msg, retval,retclass,\
+ heap1ptr, heap2ptr) \
+ if (expr) \
+ { \
+ HEAP_FREE_DATA((rvoid *) heap1ptr); /* Ignored if rnull */ \
+ HEAP_FREE_DATA((rvoid *) heap2ptr); /* Ignored if rnull */ \
+ sysDbgMsg(dml, fn, msg); \
+ exit_throw_exception(retval, retclass); \
+/*NOTREACHED*/ \
+ }
+
+#define GENERIC_FAILURE1_THROWERROR(expr, dml, fn, msg, parm1, retval, \
+ retclass, heap1ptr, heap2ptr) \
+ if (expr) \
+ { \
+ HEAP_FREE_DATA((rvoid *) heap1ptr); /* Ignored if rnull */ \
+ HEAP_FREE_DATA((rvoid *) heap2ptr); /* Ignored if rnull */ \
+ sysDbgMsg(dml, fn, msg, parm1); \
+ exit_throw_exception(retval, retclass); \
+/*NOTREACHED*/ \
+ }
+
+#define GENERIC_FAILURE2_THROWERROR(expr, dml, fn, msg, parm1, parm2, \
+ retval, retclass, heap1ptr, heap2ptr) \
+ if (expr) \
+ { \
+ HEAP_FREE_DATA((rvoid *) heap1ptr); /* Ignored if rnull */ \
+ HEAP_FREE_DATA((rvoid *) heap2ptr); /* Ignored if rnull */ \
+ sysDbgMsg(dml, fn, msg, parm1, parm2); \
+ exit_throw_exception(retval, retclass); \
+/*NOTREACHED*/ \
+ }
+
+/*@} */ /* End of grouped definitions */
+
+/*******************************************************************/
+/*!
+ * @name Support for failed system calls
+ *
+ * @brief Recover from error when loading and parsing class file
+ * by returning an @link #rnull rnull@endlink pointer, properly cast.
+ *
+ * <ul>
+ * <li>
+ * LOAD_SYSCALL_FAILURE() @link #rnull rnull@endlink pointer
+ * as (ClassFile *)
+ * </li>
+ *
+ * <li>
+ * LOAD_SYSCALL_FAILURE_ATTRIB() @link #rnull rnull@endlink pointer
+ * as (u1 *)
+ * </li>
+ * </ul>
+ *
+ *
+ * @param expr Any logical expression that returns
+ * @link #rtrue rtrue@endlink or
+ * @link #rfalse rfalse@endlink.
+ *
+ * @param msg Any text message to display to stderr if @p @b expr
+ * is @link #rtrue rtrue@endlink.
+ *
+ * @param heap1ptr Method heap block to free, or
+ * @link #rnull rnull@endlink if not needed.
+ *
+ * @param heap2ptr Method heap block to free, or
+ * @link #rnull rnull@endlink if not needed.
+ *
+ *
+ * @returns If @p @b expr is @link #rtrue rtrue@endlink, return
+ * an @link #rnull rnull@endlink pointer to the
+ * calling function, cast as shown above, else continue
+ * with inline code.
+ *
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+#define LOAD_SYSCALL_FAILURE(expr, msg, heap1ptr, heap2ptr) \
+ if (expr) \
+ { \
+ HEAP_FREE_METHOD((rvoid *) heap1ptr); \
+ HEAP_FREE_METHOD((rvoid *) heap2ptr); \
+ } \
+ GENERIC_FAILURE_PTR(expr, \
+ DMLMIN, \
+ "classfile_loadclassdata", \
+ msg, \
+ ClassFile, \
+ rnull, \
+ rnull); /* Extra ; */
+
+#define LOAD_SYSCALL_FAILURE_ATTRIB(expr, msg, heap1ptr, heap2ptr) \
+ if (expr) \
+ { \
+ HEAP_FREE_METHOD((rvoid *) heap1ptr); \
+ HEAP_FREE_METHOD((rvoid *) heap2ptr); \
+ } \
+ GENERIC_FAILURE_PTR(expr, \
+ DMLMIN, \
+ "cfattrib_loadattribute", \
+ msg, \
+ u1, \
+ rnull, \
+ rnull); /* Extra ; */
+
+/*@} */ /* End of grouped definitions */
+
+
+/*******************************************************************/
+/*!
+ *
+ * @name Architecture-dependent byte swapping macros.
+ *
+ * @brief Inline the logic to swap bytes on multi-byte elements.
+ *
+ * This is only meaningful on CONFIG_LITTLE_ENDIAN architectures.
+ * (Notice that if @p @b member does not match the pointer's
+ * type, there @e will be a compile warning or error.)
+ *
+ *
+ * @param type Which constant_pool type, CONSTANT_xxx_info,
+ * that will be used as (type *) to reference members.
+ * @param member Member of (CONSTANT_xxx_info *) to be manipulated.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ *
+ * @attention The following variables area must be defined for the
+ * CP_ITEM_SWAP_U2() and CP_ITEM_SWAP_U2 macros to work:
+ * @verbatim
+ u2 *pcpu2;
+ u4 *pcpu4;
+ @endverbatim
+ *
+ *
+ * @todo There needs to be logic implemented that can determine
+ * whether or not a particular field has been byte swapped
+ * in case a constant pool reference is made to an entry
+ * that was previously byte swapped. This has NOT been
+ * done for this ioriginal implementation because it is
+ * on a Solaris 9 machine, which is big endian.
+ *
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+#ifdef CONFIG_LITTLE_ENDIAN
+#define CP_ITEM_SWAP_U2(type, member) \
+ pcpu2 = &(((type *) &pcpd->cp)->member); \
+ MACHINE_JSHORT_SWAP_PTR(pcpu2)
+
+#define CP_ITEM_SWAP_U4(type, member) \
+ pcpu4 = &(((type *) &pcpd->cp)->member); \
+ MACHINE_JINT_SWAP_PTR(pcpu4)
+
+#else
+/* CONFIG_BIG_ENDIAN: big endian architectures have nothing to do */
+
+#define CP_ITEM_SWAP_U2(type, member)
+#define CP_ITEM_SWAP_U4(type, member)
+
+#endif
+/*@} */ /* End of grouped definitions */
+
+/*******************************************************************/
+/*!
+ * @name Generic prefix bytes.
+ *
+ * @brief Fill in empty area at start of selected structures for
+ * address alignment purposes.
+ *
+ * Fill pattern bytes are provided for (cp_info) and (attribute_info)
+ * structure alignment within (cp_info_dup) and (attribute_info_dup)
+ * structures. This assures that 2- and 4-byte alignments needed
+ * for the beginning of those structures is followed (after the first
+ * element, the @p @b tag and @p @b attribute_name_index elements,
+ * respectively).
+ *
+ * Real machine architectures that have issues with non-aligned
+ * multi-byte accesses do @e not like the fact that ClassFile
+ * structures such as cp_info begin with a single byte field followed
+ * by multi-byte fields. In like manner, structures like attribute_info
+ * have only 2- and 4-byte fields, yet may contain an odd number of
+ * bytes in their @link #attribute_info info@endlink fields.
+ * Due to the streaming nature of Java class files, subsequent
+ * attributes may thus be misaligned, even though they may only contain
+ * fields with an even number of bytes. Thus the cp_info_dup and
+ * attribute_info_dup structures were devised to suppress problems like
+ * this. When the class file is read, all structure accesses are
+ * performed on blocks of allocated memory that start on 4- or 8-byte
+ * address boundaries and pad the first few bytes so that all 2- and
+ * 4-byte accesses are on 2- or 4-byte boundaries.
+ *
+ * There are three @b FILL_INFO_DUPx fill fields for padding and
+ * three @b FILL_INFO_NOTUSED_Ux fill fields for assigning values
+ * to @b notusedXX fields.
+ *
+ * @see cp_info_dup
+ * @see attribute_info_dup
+ * @see ARCH_ODD4_ADDRESS_SIGSEGV
+ * @see ARCH_ODD2_ADDRESS_SIGSEGV
+ *
+ * @todo WATCH OUT! When changing CP_INFO_NUM_EMPTIES or
+ * ATTRIBUTE_INFO_NUM_EMPTIES, beware of not having
+ * he right number of @c @b struct->empty[x]=FILL
+ * lines in the cp_info_dup and attribute_info_dup assignments!
+ * Could eliminate these, but they are useful for
+ * debugging.
+ *
+ * @todo 4-byte unused fields are meaningful only for 64-bit
+ * implementations.
+ *
+ * @todo For 64-bit compilations, these fill patterns may need
+ * to be expanded to support 8-byte alignments for some
+ * architectures. For 32-bit compilations, nothing needs
+ * to be done. (Verify if this is so.) Remember that the
+ * @b WORDSIZE64 configuration macro is used to
+ * distinguish this mode of compilation. (See
+ * @link ./config.sh config.sh@endlink for details.)
+ *
+ */
+/*@{*/
+#define FILL_INFO_DUP0 0xbe
+#define FILL_INFO_DUP1 0xef
+#define FILL_INFO_DUP2 0x99
+
+/*
+ * Same for 1-, 2- and 4-byte @b notusedX fields.
+ */
+#define FILL_INFO_NOTUSED_U1 0x9a
+#define FILL_INFO_NOTUSED_U2 0x9ace
+#define FILL_INFO_NOTUSED_U4 0x9aceface
+/*@}*/
+
+#endif /* _cfmacros_h_included_ */
+
+/* EOF */