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 [23/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/threadutil.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/threadutil.c?rev=307257&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/threadutil.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/threadutil.c Fri Oct 7 21:27:56 2005
@@ -0,0 +1,599 @@
+/*!
+ * @file threadutil.c
+ *
+ * @brief Utilities for operating the JVM thread state model on this
+ * real machine implementation.
+ *
+ * @todo Timers for Thread.sleep() and Thread.wait() and Object.wait()
+ * that use millisecond timers @e are supported. The variation
+ * that supports higher resolution of milliseconds and nanoseconds
+ * are @e not supported, but the millisecond version is used instead.
+ *
+ * @internal This file also serves the dual purpose as a catch-all for
+ * development experiments. Due to the fact that the implementation
+ * of the Java thread and the supporting rthread structure is deeply
+ * embedded in the core of the development of this software, this
+ * file has contents that come and go during development. Some
+ * functions get staged here before deciding where they @e really
+ * go; some are interim functions for debugging, some were glue
+ * that eventually went away. Be careful to remove prototypes
+ * to such functions from the appropriate header file.
+ *
+ *
+ * @section Control
+ *
+ * \$URL: https://svn.apache.org/path/name/threadutil.c $ \$Id: threadutil.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(threadutil, c, "$URL: https://svn.apache.org/path/name/threadutil.c $ $Id: threadutil.c 0 09/28/2005 dlydick $");
+
+
+#include "jvmcfg.h"
+#include "cfmacros.h"
+#include "classfile.h"
+#include "jvm.h"
+#include "jvmclass.h"
+#include "util.h"
+
+
+/*!
+ * @brief Update the interval timer for this thread from
+ * @c @b java.lang.Thread.sleep() or from a timed
+ * @c @b java.lang.Thread.wait() or @c @b java.lang.Thread.join().
+ *
+ * This function is designed to be invoked from the timeslice interrupt
+ * handler and @e only from thence. It DOES NOT handle
+ * (millisec, nanosec) resolution, only millisecond resolution.
+ *
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ */
+
+rvoid threadutil_update_sleeptime_interval(rvoid)
+{
+ jvm_thread_index thridx;
+
+ /* Lock out the @e world during timer update */
+ pthread_mutex_lock(&pjvm->sleeplock);
+
+ for (thridx = jvm_thread_index_null;
+ thridx < JVMCFG_MAX_THREADS;
+ thridx++)
+ {
+ if ((THREAD_STATUS_INUSE & THREAD(thridx).status) &&
+ ((THREAD_STATUS_SLEEP |
+ THREAD_STATUS_JOINTIMED |
+ THREAD_STATUS_WAITTIMED ) & THREAD(thridx).status))
+ {
+ /*
+ * Perform next interval update. Stop decrementing
+ * when time reaches zero.
+ */
+ if (0 != THREAD(thridx).sleeptime)
+ {
+ THREAD(thridx).sleeptime--;
+ }
+ }
+ }
+
+ /* Unlock the @e world after timer update */
+ pthread_mutex_unlock(&pjvm->sleeplock);
+
+ return;
+
+} /* END of threadutil_update_sleeptime_interval() */
+
+
+/*!
+ * @brief Complete the UNtimed Thread.join() request and allow threads
+ * that have joined this one to resume execution.
+ *
+ * This function is typically called when a thread enters the
+ * @b COMPLETE state after finishing its JVM execution.
+ *
+ * Review state of thread table, looking for the following conditions.
+ * For those that meet them, move thread out of given state and
+ * forward to next state. Three functions are used, depending on
+ * the current state, threadutil_update_blockingevent() and
+ * threadutil_update_wait() and threadutil_update_lock():
+ *
+ * @verbatim
+
+ Condition: Current state: Next state: threadutil_update_YYY:
+ ---------- -------------- ----------- ----------------------
+
+ Thread.join() COMPLETE N/C _blockingevents()
+ (forever, where
+ current thread
+ is COMPLETE, and
+ target thread is
+ BLOCKED, and is
+ moved to UNBLOCKED)
+
+ Thread.join(n) COMPLETE N/C _blockingevents()
+ (timed, where
+ n has expired
+ on current
+ thread or it is
+ COMPLETE, and
+ target thread
+ is BLOCKED, and
+ is moved to
+ UNBLOCKED)
+
+ Thread.sleep(n) BLOCKED UNBLOCKED _blockingevents()
+ (n has expired on
+ current thread)
+
+ Interruptible I/O BLOCKED UNBLOCKED _blockingevents()
+ from class
+ java.nio.channels
+ .InterruptibleChannel
+
+ Object.wait() WAIT NOTIFY _wait()
+ (forever on
+ current thread,
+ where target object
+ lock was released)
+
+ Object.wait(n) WAIT NOTIFY _wait()
+ (timed, where
+ @c @b n
+ has expired on
+ current thread
+ or target object
+ lock was released)
+
+ One of: LOCK ACQUIRE _lock()
+ Object.notify()
+ Object.notifyAll()
+ Thread.interrupt()
+ synchronized(Object)
+ ... put thread
+ into LOCK state.
+ Now it will
+ negotiate to
+ ACQUIRE its
+ object's
+ monitor lock.
+
+
+ Thread.suspend() ANY BLOCKED threadutil_suspend()
+
+ Thread.resume() BLOCKED UNBLOCKED threadutil_resume()
+ moves a
+ Thread.suspend()
+ thread forward
+ to UNBLOCKED
+
+ @endverbatim
+ *
+ * With the exception of threadutil_suspend() and threadutil_resume(),
+ * these functions is designed to be invoked from the JVM outer loop.
+ * CAVEAT EMPTOR: Those two functions are deprecated. Use
+ * at your own risk!
+ *
+ * @todo Interruptible from class
+ * @c @b java.nio.channels.InterruptibleChannel
+ *
+ *
+ * @param thridxcurr Thread for which to examine state changes
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ */
+
+rvoid threadutil_update_blockingevents(jvm_thread_index thridxcurr)
+{
+ /* Only examine INUSE threads in selected states */
+ if (!(THREAD_STATUS_INUSE & THREAD(thridxcurr).status))
+ {
+ return;
+ }
+
+ switch (THREAD(thridxcurr).this_state)
+ {
+ case THREAD_STATE_COMPLETE: /* Untimed/untimed Thread.join() */
+
+ case THREAD_STATE_BLOCKED: /* Thread.sleep() and */
+ /*! @todo interruptible I/O req's*/
+
+ default: /* Not meaningful for this logic */
+ return;
+ }
+
+ /* sleep() -- time period expired for only this thread */
+ if ((THREAD_STATE_BLOCKED == THREAD(thridxcurr).this_state) &&
+ (THREAD_STATUS_SLEEP & THREAD(thridxcurr).status) &&
+ (0 == timeslice_get_thread_sleeptime(thridxcurr)))
+ {
+ /* Mark thread to continue now after sleep() */
+ THREAD(thridxcurr).status &= ~THREAD_STATUS_SLEEP;
+ threadstate_request_unblocked(thridxcurr);
+
+ /*
+ * Check if Thread.interrupt() was thrown
+ * against this thread.
+ *
+ * Also need to throw the exception in JVM outer loop.
+ */
+ if (THREAD_STATUS_INTERRUPTED & THREAD(thridxcurr).status)
+ {
+ THREAD(thridxcurr).status &= ~THREAD_STATUS_INTERRUPTED;
+
+ THREAD(thridxcurr).status |= THREAD_STATUS_THREW_EXCEPTION;
+
+ THREAD(thridxcurr).pThrowableEvent =
+ JVMCLASS_JAVA_LANG_INTERRUPTEDEXCEPTION;
+ }
+ }
+ else
+
+ /*! @todo First pass guess at interruptible I/O */
+ if ((THREAD_STATE_BLOCKED == THREAD(thridxcurr).this_state) &&
+ (THREAD_STATUS_INTERRUPTIBLEIO & THREAD(thridxcurr).status))
+ {
+ /*!
+ * Check if Thread.interrupt() was thrown
+ * against the interruptible I/O operation on this thread.
+ *
+ * @todo Is this the correct way to handle
+ * interruptible I/O events?
+ * Also need to throw the exception in JVM outer loop.
+ */
+ if (THREAD_STATUS_INTERRUPTED & THREAD(thridxcurr).status)
+ {
+ /* Mark thread to continue now after Thread.interrupt() */
+ THREAD(thridxcurr).status &= ~THREAD_STATUS_INTERRUPTIBLEIO;
+ threadstate_request_unblocked(thridxcurr);
+
+ THREAD(thridxcurr).status &= ~THREAD_STATUS_INTERRUPTED;
+
+ THREAD(thridxcurr).status |= THREAD_STATUS_THREW_EXCEPTION;
+
+ THREAD(thridxcurr).pThrowableEvent =
+ JVMCLASS_JAVA_NIO_CHANNELS_CLOSEDBYINTERRUPTEXCEPTION;
+ }
+ }
+ else
+
+ /*
+ * Examine Thread.join() conditions, both timed and untimed
+ */
+ if (THREAD_STATE_COMPLETE == THREAD(thridxcurr).this_state)
+ {
+ jvm_thread_index thridxjoin;
+
+ /* Skip JVMCFG_NULL_THREAD */
+ for (thridxjoin = JVMCFG_SYSTEM_THREAD;
+ thridxjoin < JVMCFG_MAX_THREADS;
+ thridxjoin++)
+ {
+ /*
+ * Skip myself
+ */
+ if (thridxcurr == thridxjoin)
+ {
+ continue;
+ }
+
+ /* Only process threads in the BLOCKED state */
+ if (THREAD_STATE_BLOCKED != THREAD(thridxjoin).this_state)
+ {
+ continue;
+ }
+
+ /*
+ * If current COMPLETE thread is the target of a join,
+ * check which type it is, timed or untimed.
+ */
+ if (thridxcurr == THREAD(thridxjoin).jointarget)
+ {
+ /* UNtimed join() -- where time period is zero/forever*/
+ if ((THREAD_STATUS_JOIN4EVER &
+ THREAD(thridxjoin).status))
+ {
+ /* Mark joined thread to be UNBLOCKED after join()*/
+ THREAD(thridxjoin).jointarget =
+ jvm_thread_index_null;
+ THREAD(thridxjoin).status &=
+ ~THREAD_STATUS_JOIN4EVER;
+ threadstate_request_unblocked(thridxjoin);
+
+ /*
+ * Check if Thread.interrupted() was thrown
+ * against this thread.
+ */
+ if (THREAD_STATUS_INTERRUPTED &
+ THREAD(thridxjoin).status)
+ {
+ THREAD(thridxjoin).status &=
+ ~THREAD_STATUS_INTERRUPTED;
+
+ THREAD(thridxjoin).status |=
+ THREAD_STATUS_THREW_EXCEPTION;
+
+ THREAD(thridxjoin).pThrowableEvent =
+ JVMCLASS_JAVA_LANG_INTERRUPTEDEXCEPTION;
+ }
+
+ }
+ else
+
+ /* TIMED join() --time period is NON-zero,now expired */
+ if ((THREAD_STATUS_JOINTIMED &
+ THREAD(thridxjoin).status) &&
+ (0 == timeslice_get_thread_sleeptime(thridxjoin)))
+ {
+ /* Mark joined thread to be UNBLOCKED after join()*/
+ THREAD(thridxjoin).jointarget =
+ jvm_thread_index_null;
+ THREAD(thridxjoin).status &=
+ ~THREAD_STATUS_JOINTIMED;
+ threadstate_request_unblocked(thridxjoin);
+
+ /*
+ * Check if Thread.interrupted() was thrown
+ * against this thread.
+ */
+ if (THREAD_STATUS_INTERRUPTED &
+ THREAD(thridxjoin).status)
+ {
+ THREAD(thridxjoin).status &=
+ ~THREAD_STATUS_INTERRUPTED;
+
+ THREAD(thridxjoin).status |=
+ THREAD_STATUS_THREW_EXCEPTION;
+
+ THREAD(thridxjoin).pThrowableEvent =
+ JVMCLASS_JAVA_LANG_INTERRUPTEDEXCEPTION;
+ }
+ }
+ }
+ }
+ }
+
+ return;
+
+} /* END of threadutil_update_blockingevents() */
+
+
+rvoid threadutil_update_wait(jvm_thread_index thridxcurr)
+{
+ /* Only examine INUSE threads in WAIT state */
+ if (!(THREAD_STATUS_INUSE & THREAD(thridxcurr).status))
+ {
+ return;
+ }
+
+ switch (THREAD(thridxcurr).this_state)
+ {
+ case THREAD_STATE_WAIT: /* Timed/untimed Object.wait() */
+ break;
+
+ default: /* Not meaningful for this logic */
+ return;
+ }
+
+
+ /* wait() -- Check for notify() or notifyAll() or interrupt() */
+ if (THREAD_STATUS_WAIT4EVER & THREAD(thridxcurr).status)
+ {
+ /*
+ * Check if Thread.interrupt() was thrown against this thread
+ * or if Object.notify() against this object by this thread.
+ *
+ * (Also need to throw the exception in JVM outer loop.)
+ */
+ if (THREAD_STATUS_INTERRUPTED & THREAD(thridxcurr).status)
+ {
+ THREAD(thridxcurr).status &= ~THREAD_STATUS_INTERRUPTED;
+
+ THREAD(thridxcurr).status |= THREAD_STATUS_THREW_EXCEPTION;
+
+ THREAD(thridxcurr).pThrowableEvent =
+ JVMCLASS_JAVA_LANG_INTERRUPTEDEXCEPTION;
+
+ /* Remove WAIT condition and move to NOTIFY state */
+ THREAD(thridxcurr).status &= ~THREAD_STATUS_WAIT4EVER;
+ threadstate_request_notify(thridxcurr);
+ }
+ else
+ if (THREAD_STATUS_NOTIFIED & THREAD(thridxcurr).status)
+ {
+ THREAD(thridxcurr).status &= ~THREAD_STATUS_NOTIFIED;
+
+ /* Remove WAIT condition and move to NOTIFY state */
+ THREAD(thridxcurr).status &= ~THREAD_STATUS_WAIT4EVER;
+ threadstate_request_notify(thridxcurr);
+ }
+ }
+ else
+
+ /* wait(n) -- TIMED, chk if monitor lock released on target object
+ or if timer expired */
+ if ((THREAD_STATUS_WAITTIMED & THREAD(thridxcurr).status) &&
+ (jvm_object_hash_null != THREAD(thridxcurr).locktarget))
+ {
+ /* Give up if timer expired */
+ if (0 == timeslice_get_thread_sleeptime(thridxcurr))
+ {
+ /* Remove @b WAIT condition and move to next state */
+ THREAD(thridxcurr).status &= ~THREAD_STATUS_WAITTIMED;
+ threadstate_request_notify(thridxcurr);
+ }
+ else
+ {
+ /*
+ * Check if Thread.interrupt() was thrown against this
+ * thread or if Object.notify() against this object by this
+ * thread.
+ *
+ * (Also need to throw the exception in JVM outer loop.)
+ */
+ if (THREAD_STATUS_INTERRUPTED & THREAD(thridxcurr).status)
+ {
+ THREAD(thridxcurr).status &= ~THREAD_STATUS_INTERRUPTED;
+
+ THREAD(thridxcurr).status |=
+ THREAD_STATUS_THREW_EXCEPTION;
+
+ THREAD(thridxcurr).pThrowableEvent =
+ JVMCLASS_JAVA_LANG_INTERRUPTEDEXCEPTION;
+
+ /* Remove WAIT condition and move to NOTIFY state */
+ THREAD(thridxcurr).status &= ~THREAD_STATUS_WAITTIMED;
+ threadstate_request_notify(thridxcurr);
+ }
+ else
+ if (THREAD_STATUS_NOTIFIED & THREAD(thridxcurr).status)
+ {
+ THREAD(thridxcurr).status &= ~THREAD_STATUS_NOTIFIED;
+
+ /* Remove WAIT condition and move to NOTIFY state */
+ THREAD(thridxcurr).status &= ~THREAD_STATUS_WAITTIMED;
+ threadstate_request_notify(thridxcurr);
+ }
+ }
+ }
+
+ return;
+
+} /* END of threadutil_update_wait() */
+
+
+rvoid threadutil_update_lock(jvm_thread_index thridxcurr)
+{
+ /* Only examine INUSE threads in LOCK state */
+ if (!(THREAD_STATUS_INUSE & THREAD(thridxcurr).status))
+ {
+ return;
+ }
+
+ switch (THREAD(thridxcurr).this_state)
+ {
+ case THREAD_STATE_LOCK: /* Lock arbitration */
+ break;
+
+ default: /* Not meaningful for this logic */
+ return;
+ }
+
+
+ /*
+ * One of java.lang.Object.notify() or java.lang.Object.notifyAll()
+ * or java.lang.Thread.interrupt() or a @c @b synchronize()
+ * block got the thread here, now try to wake up from @b LOCK with
+ * the target object's monitor lock acquired, if currently
+ * available.
+ *
+ * To do so, check if previous thread unlocked this object. If so,
+ * go lock it for use by this thread.
+ */
+ if ((jvm_object_hash_null != THREAD(thridxcurr).locktarget) &&
+ (!(OBJECT_STATUS_MLOCK & OBJECT(THREAD(thridxcurr).locktarget)
+ .status)))
+ {
+ /* If fail, arbitrate here again next time around */
+ if (rtrue ==
+ objectutil_synchronize(THREAD(thridxcurr).locktarget,
+ thridxcurr))
+ {
+ /* Move to @b ACQUIRE state */
+ THREAD(thridxcurr).status &= ~THREAD_STATUS_WAIT4EVER;
+ threadstate_request_acquire(thridxcurr);
+ }
+ }
+
+ return;
+
+} /* END of threadutil_update_lock() */
+
+
+/*!
+ * @brief Examine an object to see if a thread owns its monitor lock
+ *
+ *
+ * @param thridx Thread table index of thread to compare with.
+ *
+ * @param objhashlock Object table hash of object to examine.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if this thread owns
+ * this object's monitor lock.
+ *
+ */
+
+rboolean threadutil_holds_lock(jvm_thread_index thridx,
+ jvm_object_hash objhashlock)
+{
+ /*
+ * Make sure thread and object are both in use,
+ * make sure object is locked, then do @b BIDIRECTIONAL check
+ * to see if object and thread think each other is in sync
+ * and that @e this thread indeed @b DOES hold the lock on @e this
+ * object.
+ */
+
+ /* Prerequisite to this check */
+ if ((!(OBJECT_STATUS_INUSE & OBJECT(objhashlock).status)) ||
+ (OBJECT_STATUS_NULL & OBJECT(objhashlock).status))
+ {
+ return(rfalse);
+ }
+
+ /* Prerequisite to this check */
+ if ((!(THREAD_STATUS_INUSE & THREAD(thridx).status)) ||
+ (THREAD_STATUS_NULL & THREAD(thridx).status))
+ {
+ return(rfalse);
+ }
+
+ if ((OBJECT_STATUS_MLOCK & OBJECT(objhashlock).status) &&
+ (thridx == OBJECT(objhashlock).mlock_thridx) &&
+ ((THREAD_STATUS_WAIT4EVER |
+ THREAD_STATUS_WAITTIMED ) & THREAD(thridx).status) &&
+ (objhashlock == THREAD(thridx).locktarget))
+ {
+ return(rtrue);
+ }
+
+ return(rfalse);
+
+} /* END of threadutil_holds_lock() */
+
+
+/* EOF */
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/timeslice.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/timeslice.c?rev=307257&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/timeslice.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/timeslice.c Fri Oct 7 21:27:56 2005
@@ -0,0 +1,315 @@
+/*!
+ * @file timeslice.c
+ *
+ * @brief JVM one millisecond time slice timer.
+ *
+ * The @link rjvm.timeslice_expired pjvm->timeslice_expired@endlink
+ * flag is set by the periodic @b SIGALRM herein and tested in the JVM
+ * virtual instruction inner loop to decide when a thread has finished
+ * using its time slice.
+ *
+ * @verbatim
+ function flag value meaning
+ -------- ---------- -------
+
+ timeslice_init() set rfalse initial value
+
+ timeslice_tick() set rtrue time slice finished
+
+ jvm_run() rfalse keep running this slice
+ rtrue time slice finished
+ @endverbatim
+ *
+ *
+ * @section Control
+ *
+ * \$URL: https://svn.apache.org/path/name/timeslice.c $ \$Id: timeslice.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(timeslice, c, "$URL: https://svn.apache.org/path/name/timeslice.c $ $Id: timeslice.c 0 09/28/2005 dlydick $");
+
+
+#include <unistd.h>
+#include <signal.h>
+
+#define _REENTRANT
+#include <pthread.h>
+#include <thread.h> /* WATCH OUT! /usr/include, not application .h */
+
+#include "jvmcfg.h"
+#include "classfile.h"
+#include "jvm.h"
+#include "exit.h"
+#include "util.h"
+
+
+/*!
+ * @brief Thread control structure for use by
+ * @c @b pthread_create(3), etc.
+ */
+static pthread_t posix_thread_id;
+
+/*!
+ * @brief Start the time slicing mechanism at JVM init time
+ *
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ */
+rvoid timeslice_init()
+{
+ /* Time slice has not expired */
+ pjvm->timeslice_expired = rfalse;
+
+ /*
+ * Initialize the @link rthread#sleeptim rthread.sleeptime@endlink
+ * lock w/ defult attributes
+ */
+ pthread_mutex_init(&pjvm->sleeplock, (void *) rnull);
+
+ int rc = pthread_create(&posix_thread_id,
+ (void *) rnull,
+ timeslice_run,
+ (void *) rnull);
+
+ if (0 != rc)
+ {
+ sysErrMsg("timeslice_init", "Cannot start timer");
+ exit_jvm(EXIT_TIMESLICE_START);
+/*NOTREACHED*/
+ }
+
+ /* Declare this module initialized */
+ jvm_timeslice_initialized = rtrue;
+
+ return;
+
+} /* END of timeslice_init() */
+
+
+/*!
+ * @brief Retrieve a thread's @link rthread#sleeptime sleeptime@endlink
+ * value @e safely during read of that variable on a given thread.
+ *
+ *
+ * @param thridx Thread index of thread to read its
+ * @link rthread#sleeptime sleeptime@endlink
+ * value
+ *
+ *
+ * @returns remaining sleep time, in timer ticks
+ *
+ */
+jlong timeslice_get_thread_sleeptime(jvm_thread_index thridx)
+{
+ jlong rc;
+
+ /* Lock out the @e world while retrieving any thread's sleep time */
+ pthread_mutex_lock(&pjvm->sleeplock);
+
+ rc = THREAD(thridx).sleeptime;
+
+ /* Unlock the @e world after sleep time retrieved */
+ pthread_mutex_unlock(&pjvm->sleeplock);
+
+ /* Report sleep time value */
+ return(rc);
+
+} /* END of timeslice_get_thread_sleeptime() */
+
+
+/*!
+ * @brief Length of time slice interval as used by
+ * @c @b setitimer(2).
+ */
+static struct itimerval timeslice_period;
+
+
+/*!
+ * @brief Interval timer handler for the @b signal(SIGALRM) event.
+ *
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ *
+ * @warning Eclipse users need to remember that setting a combination
+ * of the value of @link #JVMCFG_TIMESLICE_PERIOD_ENABLE
+ JVMCFG_TIMESLICE_PERIOD_ENABLE@endlink
+ * to @link #rtrue rtrue@endlink, the value
+ * of @link #JVMCFG_TIMESLICE_PERIOD_SECONDS
+ JVMCFG_TIMESLICE_PERIOD_SECONDS@endlink to zero (0), and
+ * the value of @link #JVMCFG_TIMESLICE_PERIOD_MICROSECONDS
+ JVMCFG_TIMESLICE_PERIOD_MICROSECONDS@endlink to a low
+ * milliseconds value is @e certain to interfere with the
+ * proper operation of the GDB debug process due to the high
+ * frequency of thread context changes per second.
+ * The debug session @b will terminate without rhyme nor
+ * reason. Setting the period to several seconds will
+ * elminate this problem at the expense of time slicing
+ * on a normal basis. For unit testing, this is not a
+ * problem. For integration testing, you are on your own....
+ *
+ */
+
+static void timeslice_tick(/* void --GCC won't allow this declaration*/)
+{
+ /* Suppress SIGALRM until finished with this handler */
+ signal(SIGALRM, SIG_IGN);
+
+ /* Debug report of timer. Use ONLY for SLOW INTERVALS! */
+ if (JVMCFG_TIMESLICE_DEBUG_REPORT_MIN_SECONDS != 0) /* 0:= disable*/
+ {
+ if (JVMCFG_TIMESLICE_DEBUG_REPORT_MIN_SECONDS <=
+ timeslice_period.it_interval.tv_sec)
+ {
+ sysDbgMsg(DML9, "timeslice_tick", "tick");
+ }
+ }
+
+ /*
+ * Process signal by telling JVM to go to next time slice.
+ * Also decrement sleep interval timers for sleeping, joining,
+ * and waiting threads.
+ */
+ pjvm->timeslice_expired = rtrue;
+ threadutil_update_sleeptime_interval();
+
+ /* Set next SIGALARM for next tick of the time slice timer */
+ signal(SIGALRM, timeslice_tick);
+
+} /* END of timeslice_tick() */
+
+
+/*!
+ * @brief Interval timer thread.
+ *
+ *
+ * @param dummy The @c @b setitimer(2) system call requires
+ * a <b><code>(void *)</code></b> that has no
+ * meaning here.
+ *
+ *
+ * @returns The required <b><code>(void *)</code></b> is passed back,
+ * but this function never returns until the time slice
+ * thread is killed.
+ *
+ */
+void *timeslice_run(void *dummy)
+{
+ /* Start timer and make its first tick one period from now */
+ timeslice_period.it_interval.tv_sec =
+ JVMCFG_TIMESLICE_PERIOD_SECONDS;
+ timeslice_period.it_interval.tv_usec =
+ JVMCFG_TIMESLICE_PERIOD_MICROSECONDS;
+ timeslice_period.it_value.tv_sec =
+ JVMCFG_TIMESLICE_PERIOD_SECONDS;
+ timeslice_period.it_value.tv_usec =
+ JVMCFG_TIMESLICE_PERIOD_MICROSECONDS;
+
+ /* If timer is configured to run, get it going */
+ if (rtrue == JVMCFG_TIMESLICE_PERIOD_ENABLE)
+ {
+
+ /*
+ * Set initial SIGALARM for timer_tick(),
+ * arm timer to generate it.
+ */
+ signal(SIGALRM, timeslice_tick);
+
+ int rc = setitimer(ITIMER_REAL,
+ ×lice_period,
+ (void *) rnull);
+
+ if (0 != rc)
+ {
+ sysErrMsg("timeslice_run", "Cannot start interval timer");
+ exit_jvm(EXIT_TIMESLICE_START);
+/*NOTREACHED*/
+ }
+ }
+
+ /*
+ * Do nothing except wait on timer ticks.
+ * Eventually, the main process exits and
+ * this thread will die along with it without
+ * ever having left the while() loop.
+ *
+ * If timer is not configured to run, this loop
+ * will never see SIGALRM and timer ticks.
+ */
+
+ while(rtrue)
+ {
+ yield();
+ }
+
+/*NOTREACHED*/
+ return((void *) rnull);
+
+} /* END of timeslice_run() */
+
+
+/*!
+ * @brief Shut down the time slicing mechanism for JVM shutdown.
+ *
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ */
+rvoid timeslice_shutdown(rvoid)
+{
+ /* Suppress SIGALRM so future tick does not happen AT ALL */
+ signal(SIGALRM, SIG_IGN);
+
+ /* Ignore error */
+ pthread_cancel(posix_thread_id);
+
+ /*! @todo Is this necessary at JVM shutdown time? */
+ /* pthread_mutex_destroy(&pjvm->sleeplock); */
+
+ /* Declare this module uninitialized */
+ jvm_timeslice_initialized = rfalse;
+
+ return;
+
+} /* END of timeslice_shutdown() */
+
+
+/* EOF */
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/tmparea.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/tmparea.c?rev=307257&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/tmparea.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/tmparea.c Fri Oct 7 21:27:56 2005
@@ -0,0 +1,201 @@
+/*!
+ * @file tmparea.c
+ *
+ * @brief Create and manage temporary directory area for class files,
+ * etc.
+ *
+ *
+ * @section Control
+ *
+ * \$URL: https://svn.apache.org/path/name/tmparea.c $ \$Id: tmparea.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(tmparea, c, "$URL: https://svn.apache.org/path/name/tmparea.c $ $Id: tmparea.c 0 09/28/2005 dlydick $");
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include "jvmcfg.h"
+#include "exit.h"
+#include "heap.h"
+#include "util.h"
+
+
+/*!
+ * @brief Initialize the class area of the JVM model
+ *
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ */
+static rchar *env_tmpdir = CHEAT_AND_USE_NULL_TO_INITIALIZE;
+
+static rchar tmparea[100];
+
+rvoid tmparea_init(char **argv)
+{
+ struct stat statbfr;
+ char *argv0name = strrchr(argv[0], JVMCFG_PATHNAME_DELIMITER_CHAR);
+
+ if (rnull != argv0name)
+ {
+ argv0name++;
+ }
+ else
+ {
+ argv0name = argv[0];
+ }
+
+ int pid = getpid();
+
+ env_tmpdir = getenv("TMPDIR");
+
+ if (rnull == env_tmpdir)
+ {
+ env_tmpdir = JVMCFG_TMPAREA_DEFAULT;
+ }
+
+ sprintfLocal(tmparea,
+ "%s%ctmp.%s.%d",
+ env_tmpdir,
+ JVMCFG_PATHNAME_DELIMITER_CHAR,
+ argv0name,
+ pid);
+
+ int rc = mkdir(tmparea, 0755); /* Could use <sys/stat.h> constants*/
+
+ /* Verify existence of directory */
+ rc = stat(tmparea, &statbfr);
+
+ if (0 != rc)
+ {
+ sysErrMsg("tmparea_init",
+ "Cannot create temp directory %s",
+ tmparea);
+ exit_jvm(EXIT_TMPAREA_MKDIR);
+/*NOTREACHED*/
+ }
+ /* Declare this module initialized */
+ jvm_tmparea_initialized = rtrue;
+
+ return;
+
+} /* END of tmparea_init() */
+
+
+/*!
+ * Retrieve the temporary directory area path.
+ *
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ * @returns Null-terminated string to temp area.
+ *
+ */
+const rchar *tmparea_get()
+{
+ return((const rchar *) tmparea);
+
+} /* END of tmparea_get() */
+
+
+/*!
+ * @brief Shut down the temporary directory area after JVM execution.
+ *
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ */
+rvoid tmparea_shutdown(rvoid)
+{
+
+/* Normal method requires directory to be empty:
+ *
+ * int rc = rmdir(tmparea);
+ *
+ * if (0 != rc)
+ * {
+ * sysErrMsg("tmparea_shutdown",
+ * "Cannot remove temp directory %s",
+ * tmparea);
+ * exit_jvm(EXIT_TMPAREA_RMDIR);
+**NOTREACHED**
+ * }
+ *
+ */
+
+ struct stat statbfr;
+
+/* Since there will be temp files here, cheat just a @e little bit: */
+
+
+ rchar *rmscript = /* format spec %s make strlen longer than
+ it needs to be, but it is benign */
+ HEAP_GET_DATA(strlen(JVMCFG_TMPAREA_REMOVE_SCRIPT) +
+ strlen(tmparea) +
+ sizeof(rchar) /* NUL byte */,
+ rfalse);
+
+ sprintfLocal(rmscript, JVMCFG_TMPAREA_REMOVE_SCRIPT, tmparea);
+
+ int rc = system(rmscript);
+
+ /* Verify missing directory */
+ rc = stat(tmparea, &statbfr);
+
+ if (0 == rc)
+ {
+ sysErrMsg("tmparea_shutdown",
+ "Cannot remove temp directory %s",
+ tmparea);
+ exit_jvm(EXIT_TMPAREA_RMDIR);
+/*NOTREACHED*/
+ }
+
+ /* Declare this module uninitialized */
+ jvm_tmparea_initialized = rfalse;
+
+ return;
+
+} /* END of tmparea_shutdown() */
+
+
+/* EOF */
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/unicode.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/unicode.c?rev=307257&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/unicode.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/unicode.c Fri Oct 7 21:27:56 2005
@@ -0,0 +1,319 @@
+/*!
+ * @file unicode.c
+ *
+ * @brief Manipulate Unicode (@link #jchar jchar@endlink)[]
+ * character strings.
+ *
+ * There are three character string types in this program:
+ * null-terminated @link #rchar (rchar)@endlink strings
+ * @e ala 'C' language, UTF-8
+ * @link #CONSTANT_Utf8_info (CONSTANT_Utf8_info)@endlink strings,
+ * and Unicode @link #jchar (jchar)[]@endlink strings.
+ *
+ * Unicode (@link #jchar jchar@endlink) character utilities
+ * that do @e not involve UTF8.
+ *
+ * ALL referenced to type (@link #jchar jchar@endlink) involve
+ * Unicode characters throughout all of the code. Manipulations
+ * of them should take place @e only through these utilities.
+ *
+ *
+ * @section Control
+ *
+ * \$URL: https://svn.apache.org/path/name/unicode.c $ \$Id: unicode.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(unicode, c, "$URL: https://svn.apache.org/path/name/unicode.c $ $Id: unicode.c 0 09/28/2005 dlydick $");
+
+
+#include <string.h>
+
+#include "jvmcfg.h"
+#include "cfmacros.h"
+#include "classfile.h"
+
+
+/*
+ *
+ * Convert Unicode buffer into UTF8 buffer.
+ *
+ *
+ * @param[in] inbfr Unicode character string
+ *
+ * @param[in] length Number of bytes in @b inbfr
+ *
+ * @param[out] outbfr UTF8 byte string
+ *
+ *
+ * @returns UTF8 structure containing length and character buffer (plus
+ * tag), but return in (cp_info_dup) for full proper word
+ * alignment. When done with the data, call HEAP_FREE_DATA()
+ * on it.
+ *
+ * @c @b rc-\>bytes UTF8 version of @b inbfr string in @b outbfr
+ *
+ * @c @b rc-\>length Number of UTF8 bytes in
+ * @c @b rc-\>bytes. This will
+ * only be the same as input @b length
+ * when ALL UTF8 characters are 7-bit
+ * ASCII. It will otherwise be less
+ * than that.
+ */
+
+cp_info_dup *unicode_cnv2utf(jchar *inbfr, jshort length)
+{
+ jshort bytecnvcount = 0;
+ jshort unicodecnvcount;
+ jubyte *outbfr;
+
+ /*
+ * Make two passes through input string, one for UTF8 length (for
+ * proper heap allocation size), one for the conversion.
+ *
+ * Pass 1: calculate result size for heap allocation. This is
+ * merely a stripped-down edition of pass 2, only
+ * incrementing input buffer pointer and byte count.
+ */
+ for (unicodecnvcount = 0;
+ unicodecnvcount < length;
+ unicodecnvcount++)
+ {
+ /* Process one-byte UTF8 conversion */
+ if ((UTF8_SINGLE_MIN <= *inbfr) &&
+ (UTF8_SINGLE_MAX >= *inbfr))
+ {
+ /*
+ * Calculate a narrowing conversion,
+ * but 9 MS bits are all zeroes, so no value change.
+ */
+ inbfr++;
+ bytecnvcount++;
+ }
+ else
+ {
+ /* Calculate two-byte UTF8 conversion */
+ if (((UNICODE_DOUBLE_MIN <= *inbfr) &&
+ (UNICODE_DOUBLE_MAX >= *inbfr))
+
+ /* Also handle special case of NUL as two-byte character. */
+ || (UNICODE_DOUBLE_NUL == *inbfr))
+ {
+ outbfr++;
+ bytecnvcount++;
+
+ inbfr++;
+ bytecnvcount++;
+ }
+ else
+ {
+ /*
+ * Calculate three-byte UTF8 conversion-- all remaining
+ * cases, UNICODE_TRIPLE_MIN to UNICODE_TRIPLE_MAX
+ */
+ bytecnvcount++;
+
+ bytecnvcount++;
+
+ inbfr++;
+ bytecnvcount++;
+ }
+ }
+ } /* for () */
+
+ /*
+ * Allocate enough heap space for output string, but within the
+ * context of the output result type. The size calculation
+ * replaces generic (cp_info) with specifc (CONSTANT_Utf8_info)
+ * info, adjusting for the amount of string data to be stored
+ * into the result.
+ */
+ cp_info_dup *rc = HEAP_GET_DATA(sizeof(cp_info_dup) -
+ sizeof(cp_info) +
+ sizeof(CONSTANT_Utf8_info) -
+ sizeof(u1) +
+ bytecnvcount,
+ rfalse);
+
+ /* Prepare output structure with everything but character cnv */
+ CONSTANT_Utf8_info *pcpui = PTR_THIS_CP_Utf8(rc);
+ pcpui->tag = CONSTANT_Utf8;
+ pcpui->length = bytecnvcount;
+ outbfr = (jubyte *) pcpui->bytes;
+
+ /* Pass 2: Perform conversion itself */
+ bytecnvcount = 0;
+
+ for (unicodecnvcount = 0;
+ unicodecnvcount < length;
+ unicodecnvcount++)
+ {
+ /* Process one-byte UTF8 conversion */
+ if ((UTF8_SINGLE_MIN <= *inbfr) &&
+ (UTF8_SINGLE_MAX >= *inbfr))
+ {
+ /*
+ * Perform a narrowing conversion,
+ * but 9 MS bits are all zeroes, so no value change.
+ */
+ *outbfr++ = UTF8_SINGLE_MASK0 & ((jbyte) (*inbfr++));
+ bytecnvcount++;
+ }
+ else
+ {
+ /* Process two-byte UTF8 conversion */
+ if (((UNICODE_DOUBLE_MIN <= *inbfr) &&
+ (UNICODE_DOUBLE_MAX >= *inbfr))
+
+ /* Also handle special case of NUL as two-byte character. */
+ || (UNICODE_DOUBLE_NUL == *inbfr))
+ {
+ *outbfr = (*inbfr >> UTF8_DOUBLE_FIRST_SHIFT) &
+ UTF8_DOUBLE_FIRST_MASK0;
+ *outbfr++ |= UTF8_DOUBLE_FIRST_VAL;
+ bytecnvcount++;
+
+ *outbfr = (*inbfr++) & UTF8_DOUBLE_SECOND_MASK0;
+ *outbfr++ |= UTF8_DOUBLE_SECOND_VAL;
+ bytecnvcount++;
+ }
+ else
+ {
+ /*
+ * Process three-byte UTF8 conversion-- all remaining
+ * cases, UNICODE_TRIPLE_MIN to UNICODE_TRIPLE_MAX
+ */
+ *outbfr = (*inbfr >> UTF8_TRIPLE_FIRST_SHIFT) &
+ UTF8_TRIPLE_FIRST_MASK0;
+ *outbfr++ |= UTF8_TRIPLE_FIRST_VAL;
+ bytecnvcount++;
+
+ *outbfr = (*inbfr >> UTF8_TRIPLE_SECOND_SHIFT) &
+ UTF8_TRIPLE_SECOND_MASK0;
+ *outbfr++ |= UTF8_TRIPLE_SECOND_VAL;
+ bytecnvcount++;
+
+ *outbfr = (*inbfr++) & UTF8_TRIPLE_THIRD_MASK0;
+ *outbfr++ |= UTF8_TRIPLE_THIRD_VAL;
+ bytecnvcount++;
+ }
+ }
+ } /* for () */
+
+ return(rc);
+
+} /* END of unicode_cnv2utf() */
+
+
+/*!
+ * @brief Compare two Unicode strings of any length, @b s1 minus @b s2
+ *
+ *
+ * @param s1 First string to compare
+ *
+ * @param l1 Length of first string
+ *
+ * @param s2 Second string to compare
+ *
+ * @param l2 Length of second string
+ *
+ *
+ * @returns lexicographical difference of <b><code>s1 - s2</code></b>.
+ * Notice that the (jchar) data is unsigned, the (jshort)
+ * result is signed, due to the arithmetic nature of the
+ * calculation.
+ *
+ */
+jshort unicode_strcmp(jchar *s1, u2 l1, jchar *s2, u2 l2)
+{
+ /* Compare shortest common run length */
+ rint cmplen = (l1 < l2) ? l1 : l2;
+
+ /* Perform Unicode strlen() function */
+ rint i;
+ jshort rc = 0;
+
+ for (i = 0; i < cmplen; i++)
+ {
+ rc = s1[i] - s2[i];
+ if (0 != rc)
+ {
+ break;
+ }
+ }
+
+ /*
+ * THIS LOGIC IS THE SAME AS FOR s1_s2_strncmp(), BUT
+ * OPERATES ON (jchar) instead of (rchar).
+ */
+
+ /* Return from several permutations of strlen */
+ if (l1 == l2)
+ {
+ return(rc);
+ }
+ else
+ if (l1 > l2)
+ {
+ /*
+ * If a difference existed, return it, else use
+ * the last character of @b s1 as character minus
+ * NUL byte (or zero), which equals character.
+ */
+ if (0 != rc)
+ {
+ return(rc);
+ }
+
+ /*
+ * First character of @b s1 past length of @b s2
+ */
+ return((jshort) s1[l2]);
+ }
+ else
+ {
+ /* If a difference existed, return it, else use end of @b s2 */
+ /*
+ * If a difference existed, return it, else use
+ * the last character of @b s1 as NUL byte (or zero)
+ * minus character, which equals negative of character.
+ */
+ if (0 != rc)
+ {
+ return(rc);
+ }
+
+ /* First character of @b s2 past length of @b s1 */
+ return((jshort) (0 - s2[l1]));
+ }
+} /* END of unicode_strcmp() */
+
+
+/* EOF */
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/unicode.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/unicode.h?rev=307257&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/unicode.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/unicode.h Fri Oct 7 21:27:56 2005
@@ -0,0 +1,61 @@
+#ifndef _unicode_h_defined_
+#define _unicode_h_defined_
+
+/*!
+ * @file unicode.h
+ *
+ * @brief Manipulate Unicode (@link #jchar jchar@endlink)[]
+ * character strings.
+ *
+ * There are three character string types in this program:
+ * null-terminated @link #rchar (rchar)@endlink strings
+ * @e ala 'C' language, UTF-8
+ * @link #CONSTANT_Utf8_info (CONSTANT_Utf8_info)@endlink strings,
+ * and Unicode @link #jchar (jchar)[]@endlink strings.
+ *
+ *
+ * @section Control
+ *
+ * \$URL: https://svn.apache.org/path/name/unicode.h $ \$Id: unicode.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(unicode, h, "$URL: https://svn.apache.org/path/name/unicode.h $ $Id: unicode.h 0 09/28/2005 dlydick $");
+
+
+/* Prototypes for functions in 'unicode.c' */
+
+extern cp_info_dup *unicode_cnv2utf(jchar *inbfr, jshort length);
+
+extern jshort unicode_strcmp(jchar *us1, u2 l1, jchar *us2, u2 l2);
+
+#endif /* _unicode_h_defined_ */
+
+
+/* EOF */
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/utf.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/utf.c?rev=307257&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/utf.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/utf.c Fri Oct 7 21:27:56 2005
@@ -0,0 +1,836 @@
+/*!
+ * @file utf.c
+ *
+ * @brief Manipulate UTF-8 CONSTANT_Utf8_info character strings.
+ *
+ * There are three character string types in this program:
+ * null-terminated @link #rchar (rchar)@endlink strings
+ * @e ala 'C' language, UTF-8
+ * @link #CONSTANT_Utf8_info (CONSTANT_Utf8_info)@endlink strings,
+ * and Unicode @link #jchar (jchar)[]@endlink strings.
+ *
+ * Convert one or UTF-8 (jbyte) bytes to and from Unicode (jchar)
+ * characters, plus related functions, like comparison and string
+ * length.
+ *
+ * Why are these functions called @b utf_XXX() instead of @b utf8_XXX()?
+ * Originally, they were called such, but when the JDK 1.5 class file
+ * spec, section 4, was reviewed (after working with the 1.2/1.4
+ * versions), it was discovered that certain other @b UTF-xx formats
+ * were also provided in the spec, even if not accurately defined.
+ * (Due to errors in the revised class file specification, the 21-bit
+ * UTF characters (6 bytes) will not be implemented until a definitive
+ * correction is located. However, in anticipation of this correction,
+ * the functions are now named utf_XXX() without respect to character
+ * bit width.) Notice, however, that the spec, section 4, defines a
+ * CONSTANT_Utf8 and a CONSTANT_Utf8_info. Therefore, these
+ * designations will remain in the code unless changed in the spec.
+ *
+ *
+ * @section Control
+ *
+ * \$URL: https://svn.apache.org/path/name/utf.c $ \$Id: utf.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(utf, c, "$URL: https://svn.apache.org/path/name/utf.c $ $Id: utf.c 0 09/28/2005 dlydick $");
+
+
+#include <string.h>
+
+#include "jvmcfg.h"
+#include "cfmacros.h"
+#include "classfile.h"
+#include "nts.h"
+#include "util.h"
+
+
+/*!
+ * Store a Unicode @c @b ? when invalid UTF state found,
+ * adj return code
+ */
+#define MAP_INVALID_UTF8_TO_QUESTION_MARK *outbfr++ = (jchar) '?'; \
+ inbfr++
+
+/*! Detect NUL character and quit when found */
+#define RETURN_IF_NUL_BYTE if (UTF8_FORBIDDEN_ZERO == *inbfr) \
+ {return(charcnvcount); }
+
+/*!
+ * @brief Convert UTF8 buffer into Unicode buffer.
+ *
+ *
+ * @param[in] utf_inbfr UTF string structure
+ *
+ * @param[out] outbfr Buffer for resulting Unicode character string
+ *
+ *
+ * @returns Two returns, one a buffer, the other a count:
+ *
+ * *outbfr Unicode version of @b utf_inbfr string in @b outbfr
+ *
+ * charcnvcount (Return value of function) Number of Unicode
+ * characters in @b outbfr. This will only be the
+ * same as @b length when ALL UTF characters are
+ * ASCII. It will otherwise be less than that.
+ *
+ * SPEC AMBIGUITY: In case of invalid characters, a Unicode
+ * @c @b ? is inserted and processing continues. In this way,
+ * the result string will still be invalid, but at least it will be
+ * proper Unicode. This may prove more than is necessary, but the
+ * spec says nothing at all about this matter. Since the NUL character
+ * may not appear in UTF-8, if a buffer is terminated by a NUL in the
+ * first @c @b utf_inbfr->length bytes, termination will be
+ * assumed. If a @link #UTF8_FORBIDDEN_MIN UTF8_FORBIDDEN_xxx@endlink
+ * character is read, it is converted to a Unicode @c @b ? also.
+ *
+ */
+
+jshort utf_utf2unicode(CONSTANT_Utf8_info *utf_inbfr, jchar *outbfr)
+{
+ jshort charcnvcount;
+
+ jubyte *inbfr = (jubyte *) utf_inbfr->bytes;
+
+ for (charcnvcount = 0;
+ charcnvcount < utf_inbfr->length;
+ charcnvcount++)
+ {
+ RETURN_IF_NUL_BYTE;
+ if (UTF8_SINGLE_MAX >= *inbfr)
+ {
+ /* Process one-byte form */
+ *outbfr++ = (jchar) *inbfr++;
+ }
+ else
+ {
+ /* Process two-byte form */
+ if (UTF8_TRIPLE_FIRST_VAL > *inbfr)
+ {
+ if (UTF8_DOUBLE_FIRST_VAL > *inbfr)
+ {
+ MAP_INVALID_UTF8_TO_QUESTION_MARK;
+ continue;
+ }
+
+ /* Store top half of Unicode character */
+ *outbfr = (jchar)
+ (((*inbfr++) & UTF8_DOUBLE_FIRST_MASK0)
+ << UTF8_DOUBLE_FIRST_SHIFT);
+
+ /* Abort if next byte is NUL */
+ RETURN_IF_NUL_BYTE;
+
+ if ((UTF8_DOUBLE_SECOND_VAL | UTF8_DOUBLE_SECOND_MASK0)
+ < *inbfr)
+ {
+ /*
+ * Map invalid forms to @c @b ? and
+ * move to next char
+ */
+ MAP_INVALID_UTF8_TO_QUESTION_MARK;
+ continue;
+ }
+
+ /* Store bottom half of Unicode character */
+ *outbfr++ |= (jchar)
+ ((*inbfr++) & UTF8_DOUBLE_SECOND_MASK0);
+ }
+ else
+ {
+ /* Process three-byte form */
+ if ((UTF8_TRIPLE_FIRST_VAL | UTF8_TRIPLE_FIRST_MASK0)
+ < *inbfr)
+ {
+ /* This also considers UTF8_FORBIDDEN_MIN/MAX
+ bytes */
+ MAP_INVALID_UTF8_TO_QUESTION_MARK;
+ continue;
+ }
+
+ /* Store top third of Unicode character */
+ *outbfr = (jchar)
+ (((*inbfr++) & UTF8_TRIPLE_FIRST_MASK0)
+ << UTF8_TRIPLE_FIRST_SHIFT);
+
+ /* Abort if next byte is NUL */
+ RETURN_IF_NUL_BYTE;
+
+ if ((UTF8_TRIPLE_SECOND_VAL | UTF8_TRIPLE_SECOND_MASK0)
+ < *inbfr)
+ {
+ /*
+ * Map invalid forms to @c @b ? and
+ * move to next char
+ */
+ MAP_INVALID_UTF8_TO_QUESTION_MARK;
+ continue;
+ }
+
+ /* Store middle third of Unicode character */
+ *outbfr |= (jchar)
+ (((*inbfr++) & UTF8_TRIPLE_SECOND_MASK0)
+ << UTF8_TRIPLE_SECOND_SHIFT);
+
+ /* Abort if next byte is NUL */
+ RETURN_IF_NUL_BYTE;
+
+ if ((UTF8_TRIPLE_THIRD_VAL | UTF8_TRIPLE_THIRD_MASK0)
+ < *inbfr)
+ {
+ /*
+ * Map invalid forms to @c @b ? and
+ * move to next char
+ */
+ MAP_INVALID_UTF8_TO_QUESTION_MARK;
+ continue;
+ }
+
+ /* Store bottom third of Unicode character */
+ *outbfr++ |= (jchar)
+ ((*inbfr++) & UTF8_TRIPLE_THIRD_MASK0);
+ }
+ }
+
+ } /* for (i) */
+
+ /* Done. Return number of characters processed */
+ return(charcnvcount);
+
+} /* END of utf_utf2unicode() */
+
+
+/*!
+ * @brief Convert a UTF string from a (CONSTANT_Utf8_info *) into a
+ * null-terminated string by allocating heap and copying the UTF data.
+ *
+ * When done with result, perform HEAP_FREE_DATA(result).
+ *
+ * @param src Pointer to UTF string, most likely from constant pool
+ *
+ * @returns Null-terminated string in heap or
+ * @link #rnull rnull@endlink if heap alloc error.
+ *
+ */
+
+rchar *utf_utf2prchar(CONSTANT_Utf8_info *src)
+{
+ /* Allocate heap for UTF data plus NUL byte */
+ rchar *rc = HEAP_GET_DATA(sizeof(rchar) + src->length, rfalse);
+
+ /* Copy to heap area */
+ memcpy(rc, &src->bytes[0], src->length);
+
+ /* Append NUL character */
+ rc[src->length] = '\0';
+
+ /* Produce result */
+ return(rc);
+
+} /* END of utf_utf2prchar() */
+
+
+/*!
+ * @brief Compare two strings of any length, and potentially neither
+ * null-terminated, that is, could be a UTF string.
+ *
+ * If strings are of equal length, this function is equivalent
+ * to @c @b strcmp(3). If not of equal length, result is like
+ * comparing @c @b n bytes of @c @b strncmp(3), where non-equal
+ * result is returned, but if equal result, it is like
+ * @c @b n+1, where the final byte is a @c @b \\0 (NUL)
+ * character, so longer string's @c @b n+1 character
+ * is reported, either as positive value (@b s1 longer) or as
+ * negative value (@b s2 longer).
+ *
+ * This function should be used on ALL string comparisons that
+ * potentially involve lack of NUL termination, namely, @e anything
+ * to do with UTF strings of any sort. It is recommended also for
+ * any null-terminated string just so all string comparisons work
+ * @e exactly alike, no matter whether (rchar *) or UTF, whether of
+ * equal length or not.
+ *
+ * @param s1 (rchar *) to first string
+ *
+ * @param l1 Length of string @b s1, regardless of any
+ * null termination being present or absent
+ * in @b s1.
+ *
+ * @param s2 (rchar *) to second string
+ *
+ * @param l2 length of string @b s2, regardless of any
+ * null termination being present or absent
+ * in @b s2.
+ *
+ * @returns lexicographical difference of <b><code>s1 - s2</code></b>.
+ * Notice that the (rchar) data is implicitly unsigned
+ * (although the actual signage is left to the compiler),
+ * while the (jbyte) result is explicitly signed, due to the
+ * arithmetic nature of the calculation.
+ *
+ */
+static jbyte s1_s2_strncmp(u1 *s1, int l1, u1 *s2, int l2)
+{
+ /* Compare shortest common run length */
+ int cmplen = (l1 < l2) ? l1 : l2;
+ jbyte rc = strncmp(s1, s2, cmplen);
+
+ /*
+ * THIS LOGIC IS THE SAME AS FOR unicode_strncmp(), BUT
+ * OPERATES ON (jchar) instead of (rchar)
+ */
+
+ /* Return from several permutations of strlen */
+ if (l1 == l2)
+ {
+ return(rc);
+ }
+ else
+ if (l1 > l2)
+ {
+ /*
+ * If a difference existed, return it, else use
+ * the last character of @b s1 as character minus
+ * NUL byte (or zero), which equals character.
+ */
+ if (0 != rc)
+ {
+ return(rc);
+ }
+
+ /*
+ * First character of @b s1 past length of @b s2
+ */
+ return((jbyte) s1[l2]);
+ }
+ else
+ {
+ /* If a difference existed, return it, else use end of @b s2 */
+ /*
+ * If a difference existed, return it, else use
+ * the last character of @b s1 as NUL byte (or zero)
+ * minus character, which equals negative of character.
+ */
+ if (0 != rc)
+ {
+ return(rc);
+ }
+
+ /* First character of @b s2 past length of @b s1 */
+ return((jbyte) (0 - s2[l1]));
+ }
+} /* END of s1_s2_strncmp() */
+
+
+/*!
+ * @brief Compare two UTF strings from constant_pool, @b s1 minus @b s2
+ *
+ * @param s1 First of two UTF strings to compare
+ *
+ * @param s2 Second of two UTF strings to compare
+ *
+ * @returns lexicographical value of first difference in strings,
+ * else 0.
+ *
+ */
+jbyte utf_utf_strcmp(CONSTANT_Utf8_info *s1, CONSTANT_Utf8_info *s2)
+{
+ /* Perform unified comparison of both UTF strings */
+ return(s1_s2_strncmp(s1->bytes, s1->length, s2->bytes, s2->length));
+
+} /* END of utf_utf_strcmp() */
+
+
+/*!
+ * @brief Compare contents of null-terminated string to contents of
+ * a UTF string from a class file structure.
+ *
+ * @param s1 Null-terminated string name
+ *
+ * @param pcfs2 ClassFile where UTF string is found
+ *
+ * @param cpidx2 Index in @b pcfs2 constant_pool of UTF string
+ *
+ *
+ * @returns lexicographical value of first difference in strings,
+ * else 0.
+ *
+ */
+jbyte utf_prchar_pcfs_strcmp(rchar *s1,
+ ClassFile *pcfs2,
+ jvm_constant_pool_index cpidx2)
+{
+ int l1 = strlen(s1);
+
+ u1 *s2 = PTR_CP_THIS_STRNAME(pcfs2, cpidx2);
+
+ int l2 = CP_THIS_STRLEN(pcfs2, cpidx2);
+
+ /* Perform unified comparison of null-terminated vs UTF string */
+ return(s1_s2_strncmp(s1, l1, s2, l2));
+
+} /* END of utf_prchar_pcfs_strcmp() */
+
+
+/*!
+ * @brief Compare contents of UTF string to contents of a UTF string
+ * from a class file structure.
+ *
+ * @param s1 UTF string name
+ *
+ * @param pcfs2 ClassFile where UTF string is found
+ *
+ * @param cpidx2 Index in @b pcfs2 constant_pool of UTF string
+ *
+ *
+ * @returns lexicographical value of first difference in strings,
+ * else 0.
+ *
+ */
+jbyte utf_pcfs_strcmp(CONSTANT_Utf8_info *s1,
+ ClassFile *pcfs2,
+ jvm_constant_pool_index cpidx2)
+{
+ u1 *s2 = PTR_CP_THIS_STRNAME(pcfs2, cpidx2);
+
+ int l2 = CP_THIS_STRLEN(pcfs2, cpidx2);
+
+ /* Perform unified comparison of null-terminated vs UTF string */
+ return(s1_s2_strncmp(s1->bytes, s1->length, s2, l2));
+
+} /* END of utf_pcfs_strcmp() */
+
+
+/*!
+ * @brief Common generic comparison, all parameters regularized.
+ *
+ * Compare a UTF or null-terminated string containing a
+ * formatted or unformatted class name with an @e unformatted UTF
+ * string from constant_pool.
+ * Compare @b s1 minus @b s2, but skipping, where applicable,
+ * the @b s1 initial BASETYPE_CHAR_L and the terminating
+ * BASETYPE_CHAR_L_TERM, plus any array dimension modifiers. The second
+ * string is specified by a constant_pool index. Notice that there
+ * are @e NO formatted class string names in the (CONSTANT_Class_info)
+ * entries of the constant_pool because such would be redundant. (Such
+ * entries @e are the @e formal definition of the class.)
+ *
+ *
+ * @param s1 UTF string pointer to u1 array of characters.
+ *
+ * @param l1 length of @b s1.
+ *
+ * @param pcfs2 ClassFile structure containing second string
+ * (containing an @e unformatted class name)
+ *
+ * @param cpidx2 constant_pool index of CONSTANT_Class_info entry
+ * whose name will be compared (by getting its
+ * @link CONSTANT_Class_info#name_index name_index@endlink
+ * and the UTF string name of it)
+ *
+ *
+ * @returns lexicographical value of first difference in strings,
+ * else 0.
+ *
+ */
+static jbyte utf_common_classname_strcmp(u1 *s1,
+ int l1,
+ ClassFile *pcfs2,
+ jvm_constant_pool_index cpidx2)
+{
+ CONSTANT_Class_info *pci = PTR_CP_ENTRY_CLASS(pcfs2, cpidx2);
+
+ u1 *s2 = PTR_CP_THIS_STRNAME(pcfs2, pci->name_index);
+ int l2 = CP_THIS_STRLEN(pcfs2, pci->name_index);
+
+ if (rtrue == nts_prchar_isclassformatted(s1))
+ {
+ s1++; /* Point PAST the BASETYPE_CHAR_L character */
+ l1--;
+
+ u1 *ps1end = strchr(s1, BASETYPE_CHAR_L_TERM);
+
+ /* Should @e always be @link #rtrue rtrue@endlink */
+ if (rnull != ps1end)
+ {
+ l1 = ps1end - (u1 *) s1; /* Adjust for terminator */
+ }
+ }
+
+
+ /*
+ * Perform unified comparison of (possibly) null-terminated
+ * vs UTF string
+ */
+ return(s1_s2_strncmp(s1, l1, s2, l2));
+
+} /* END of utf_common_classname_strcmp() */
+
+
+/*!
+ * @brief Compare a null-terminated string containing a
+ * formatted or unformatted class name with an @e unformatted UTF
+ * string from constant_pool.
+ *
+ *
+ * @param s1 Null-terminated string to compare, containing
+ * formatted @e or unformatted class name
+ * (utf_prchar_classname_strcmp() only).
+ *
+ * @param pcfs2 ClassFile structure containing second string
+ * (containing an @e unformatted class name)
+ *
+ * @param cpidx2 constant_pool index of CONSTANT_Class_info entry
+ * whose name will be compared (by getting its
+ * @link CONSTANT_Class_info#name_index name_index@endlink
+ * and the UTF string name of it)
+ *
+ *
+ * @returns lexicographical value of first difference in strings,
+ * else 0.
+ *
+ */
+jbyte utf_prchar_classname_strcmp(rchar *s1,
+ ClassFile *pcfs2,
+ jvm_constant_pool_index cpidx2)
+{
+ return(utf_common_classname_strcmp((u1 *) s1,
+ strlen(s1),
+ pcfs2,
+ cpidx2));
+
+} /* END of utf_prchar_classname_strcmp() */
+
+
+/*!
+ * @brief Compare a UTF string containing a
+ * formatted or unformatted class name with an @e unformatted UTF
+ * string from constant_pool.
+ *
+ *
+ * @param s1 UTF string to compare, containing formatted @e or
+ * unformatted class name.
+ *
+ * @param pcfs2 ClassFile structure containing second string
+ * (containing an @e unformatted class name)
+ *
+ * @param cpidx2 constant_pool index of CONSTANT_Class_info entry
+ * whose name will be compared (by getting its
+ * @link CONSTANT_Class_info#name_index name_index@endlink
+ * and the UTF string name of it)
+ *
+ *
+ * @returns lexicographical value of first difference in strings,
+ * else 0.
+ *
+ */
+jbyte utf_classname_strcmp(CONSTANT_Utf8_info *s1,
+ ClassFile *pcfs2,
+ jvm_constant_pool_index cpidx2)
+{
+ return(utf_common_classname_strcmp(s1->bytes,
+ s1->length,
+ pcfs2,
+ cpidx2));
+
+} /* END of utf_classname_strcmp() */
+
+
+/*!
+ * @brief Report the number of array dimensions prefixing a Java type
+ * string.
+ *
+ * No overflow condition is reported since it is assumed that @b inbfr
+ * is formatted with correct length. Notice that because this logic
+ * checks @e only for array specifiers and does not care about the rest
+ * of the string, it may be used to evaluate field descriptions, which
+ * will not contain any class formatting information.
+ *
+ * If there is even a @e remote possibility that more than
+ * CONSTANT_MAX_ARRAY_DIMS dimensions will be found, compare
+ * the result of this function with the result of utf_isarray().
+ * If there is a discrepancy, then there was an overflow here.
+ * Properly formatted class files will @e never contain code with
+ * this condition.
+ *
+ * @note This function is identical to nts_get_arraydims() except
+ * that it works on (CONSTANT_Utf8_info *) instead of (rchar *).
+ *
+ *
+ * @param inbfr CONSTANT_Utf8_info string.
+ *
+ *
+ * @returns Number of array dimensions in string. For example,
+ * this string contains three array dimensions:
+ *
+ * @c @b [[[Lsome/path/name/filename;
+ *
+ * If more than CONSTANT_MAX_ARRAY_DIMS are located, the
+ * result is zero-- no other error is reported.
+ *
+ */
+
+jvm_array_dim utf_get_utf_arraydims(CONSTANT_Utf8_info *inbfr)
+{
+ /* Make return code wider than max to check overflow */
+ u4 rc = 0;
+
+ /* Start scanning at beginning of string */
+ u1 *pclsname = (u1 *) &inbfr->bytes[0];
+
+ /* Keep scanning until no more array specifications are found */
+ while (BASETYPE_CHAR_ARRAY == *pclsname++)
+ {
+ rc++;
+ }
+
+ /* Check overflow, return default if so, else number of dimensions*/
+ if (CONSTANT_MAX_ARRAY_DIMS < rc)
+ {
+ return(LOCAL_CONSTANT_NO_ARRAY_DIMS);
+ }
+ else
+ {
+ /* Perform narrowing conversion into proper type for max */
+ return((jvm_array_dim) rc);
+ }
+
+} /* END of utf_get_utf_arraydims() */
+
+
+/*!
+ * @brief Test whether or not a Java type string is an array or not.
+ *
+ *
+ * @param inbfr CONSTANT_Utf8_info string.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if this is an array
+ * specfication, else @link #rfalse rfalse@endlink.
+ *
+ */
+
+rboolean utf_isarray(CONSTANT_Utf8_info *inbfr)
+{
+ return((BASETYPE_CHAR_ARRAY == (u1)inbfr->bytes[0]) ? rtrue : rfalse);
+
+} /* END of utf_isarray() */
+
+
+/*!
+ * @brief Convert and an un-formatted class name UTF string (of the
+ * type @c @b ClassName and not of type
+ * @c @b [[[LClassName) from a (CONSTANT_Utf8_info *) into
+ * a null-terminated string with Java class formatting items. Result
+ * is delivered in a heap-allocated buffer. When done with result,
+ * perform HEAP_FREE_DATA(result) to return that buffer to the heap.
+ *
+ * This function @e will work on formatted class names
+ * @c @b [[[LClassName; and the difference is benign,
+ * but that is not its purpose.
+ *
+ * @param src Pointer to UTF string, most likely from constant pool
+ *
+ * @returns Null-terminated string @c @b LClasSName; in heap
+ * or @link #rnull rnull@endlink if heap alloc error.
+ *
+ */
+
+rchar *utf_utf2prchar_classname(CONSTANT_Utf8_info *src)
+{
+ /* Retrieve string from UTF data first */
+ rchar *pstr = utf_utf2prchar(src);
+
+ if (rnull == pstr)
+ {
+ return(pstr);
+ }
+
+ /* Allocate heap for formatted version */
+
+ rchar *rc = HEAP_GET_DATA(sizeof(rchar) + /* Type specifier */
+ sizeof(rchar) + /* Type spec terminator */
+ sizeof(rchar) + /* NUL character */
+ src->length, /* data */
+ rfalse);
+
+ int pstrlen = strlen(pstr);
+ rboolean isfmt = nts_prchar_isclassformatted(pstr);
+
+ if (rtrue == isfmt)
+ {
+ /*
+ * Copy entire string plus NUL character into heap area,
+ * ignoring excess allocation when formatting is @e added
+ * to string.
+ */
+ memcpy(&rc[0], pstr, pstrlen);
+ rc[pstrlen] = '\0';
+ }
+ else
+ {
+ /* Initial formatting */
+ rc[0] = BASETYPE_CHAR_L;
+
+ /* Copy to heap area */
+ memcpy(&rc[1], pstr, pstrlen);
+
+ /* Append end formatting and NUL character */
+ rc[1 + pstrlen] = BASETYPE_CHAR_L_TERM;
+ rc[2 + pstrlen] = '\0';
+ }
+
+ HEAP_FREE_DATA(pstr);
+
+
+ /* Produce result */
+ return(rc);
+
+} /* END of utf_utf2prchar_classname() */
+
+
+/*!
+ * @brief Verify if a UTF string contains class formatting or not.
+ *
+ *
+ * @param src Pointer to UTF string, most likely from constant pool
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if string is formtted as
+ * @c @b LClasSName; but
+ * @link #rfalse rfalse@endlink otherwise, may also have
+ * array descriptor prefixed, thus @c @b [[LClassName;
+ *
+ *
+ * @note This function works just like nts_prchar_isclassformatted()
+ * except that it works on (CONSTANT_Utf8_info) strings rather
+ * than on (rchar *) strings.
+ */
+
+rboolean utf_utf_isclassformatted(CONSTANT_Utf8_info *src)
+{
+ jvm_utf_string_index utfidx;
+ rboolean rc = rfalse;
+
+ /* Chk array or class specifier. If neither, cannot be formatted */
+ switch (src->bytes[0])
+ {
+ case BASETYPE_CHAR_ARRAY:
+ case BASETYPE_CHAR_L:
+ break;
+ default:
+ return(rfalse);
+ }
+
+
+ /*
+ * Now assume a potentially formatted string.
+ * Check for termination byte next. If not present,
+ * nothing else matters and string cannot be formatted.
+ */
+ u1 *pbytes = src->bytes;
+
+ for (utfidx = 0; utfidx < src->length; utfidx++)
+ {
+ if (BASETYPE_CHAR_L_TERM == pbytes[utfidx])
+ {
+ rc = rtrue;
+ break;
+ }
+ }
+
+ /* If not terminated, then cannot be class formatted */
+ if (rfalse == rc)
+ {
+ return(rc);
+ }
+
+ /* Check initial formatting, including array spec */
+ jvm_array_dim arraydims = utf_get_utf_arraydims(src);
+
+ /* If any array specs, look immediately past them for class spec */
+ if (BASETYPE_CHAR_L == pbytes[arraydims])
+ {
+ return(rtrue);
+ }
+ else
+ {
+ return(rfalse);
+ }
+
+} /* END of utf_utf_isclassformatted() */
+
+
+/*!
+ *
+ * @brief Strip a UTF string of any class formatting it contains
+ * and return result in a heap-allocated buffer.
+ *
+ * When done with this result, perform HEAP_DATA_FREE(result) to
+ * return buffer to heap.
+ *
+ *
+ * @param inbfr Pointer to UTF string that is potentially formatted
+ * as @c @b LClassName; and which may also have
+ * array descriptor prefixed, thus
+ * @c @b [[LClassName; . This will
+ * typically be an entry from the constant_pool.
+ *
+ *
+ * @returns heap-allocated buffer containing @c @b ClassName
+ * with no formatting, regardless of input formatting or
+ * lack thereof.
+ *
+ *
+ * @note This function works just like
+ * nts_prchar2prchar_unformatted_classname() except that
+ * it takes a (CONSTANT_Utf8_info) string rather
+ * than a (rchar *) string and returns a (CONSTANT_Utf8_info *).
+ *
+ */
+
+cp_info_dup *utf_utf2utf_unformatted_classname(cp_info_dup *inbfr)
+{
+ rchar *pstr = utf_utf2prchar(PTR_THIS_CP_Utf8(inbfr));
+
+ rchar *punf = nts_prchar2prchar_unformatted_classname(pstr);
+
+ HEAP_FREE_DATA(pstr);
+
+ cp_info_dup *rc = nts_prchar2utf(punf);
+
+ HEAP_FREE_DATA(punf);
+
+ return(rc);
+
+} /* END of utf_utf2utf_unformatted_classname() */
+
+
+/* EOF */
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/utf.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/utf.h?rev=307257&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/utf.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/utf.h Fri Oct 7 21:27:56 2005
@@ -0,0 +1,91 @@
+#ifndef _utf_h_defined_
+#define _utf_h_defined_
+
+/*!
+ * @file utf.h
+ *
+ * @brief Manipulate UTF-8 CONSTANT_Utf8_info character strings.
+ *
+ * There are three character string types in this program:
+ * null-terminated @link #rchar (rchar)@endlink strings
+ * @e ala 'C' language, UTF-8
+ * @link #CONSTANT_Utf8_info (CONSTANT_Utf8_info)@endlink strings,
+ * and Unicode @link #jchar (jchar)[]@endlink strings.
+ *
+ *
+ * @section Control
+ *
+ * \$URL: https://svn.apache.org/path/name/utf.h $ \$Id: utf.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
+ *
+ */
+
+
+/* Prototypes for functions in 'utf.c' */
+
+ARCH_COPYRIGHT_APACHE(utf, h, "$URL: https://svn.apache.org/path/name/utf.h $ $Id: utf.h 0 09/28/2005 dlydick $");
+
+extern jshort utf_utf2unicode(CONSTANT_Utf8_info *utf_inbfr,
+ jchar *outbfr);
+
+extern rchar *utf_utf2prchar(CONSTANT_Utf8_info *src);
+
+extern rchar *utf_utf2prchar_classname(CONSTANT_Utf8_info *src);
+
+extern jbyte utf_utf_strcmp(CONSTANT_Utf8_info *s1,
+ CONSTANT_Utf8_info *s2);
+
+extern jbyte utf_prchar_pcfs_strcmp(rchar *s1,
+ ClassFile *pcfs,
+ jvm_constant_pool_index cpidx2);
+
+extern jbyte utf_pcfs_strcmp(CONSTANT_Utf8_info *s1,
+ ClassFile *pcfs,
+ jvm_constant_pool_index cpidx2);
+
+extern jbyte utf_prchar_classname_strcmp(rchar *s1,
+ ClassFile *pcfs,
+ jvm_constant_pool_index cpidx2);
+
+extern jbyte utf_classname_strcmp(CONSTANT_Utf8_info *s1,
+ ClassFile *pcfs2,
+ jvm_constant_pool_index cpidx2);
+
+extern jvm_array_dim utf_get_utf_arraydims(CONSTANT_Utf8_info *inbfr);
+
+extern rboolean utf_utf_isarray(CONSTANT_Utf8_info *inbfr);
+
+extern rboolean utf_utf_isclassformatted(CONSTANT_Utf8_info *src);
+
+extern cp_info_dup
+ *utf_utf2utf_unformatted_classname(cp_info_dup *inbfr);
+
+#endif /* _utf_h_defined_ */
+
+
+/* EOF */
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/util.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/util.h?rev=307257&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/util.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/util.h Fri Oct 7 21:27:56 2005
@@ -0,0 +1,241 @@
+#ifndef _util_h_defined_
+#define _util_h_defined_
+
+/*!
+ * @file util.h
+ *
+ * @brief Miscellaneous utility macros and function prototypes.
+ *
+ * Source files whose function prototypes are defined
+ * herein include:
+ *
+ * @link jvm/src/argv.c argv.c@endlink
+ *
+ * @link jvm/src/bytegames.c bytegames.c@endlink
+ *
+ * @link jvm/src/classpath.c classpath.c@endlink
+ *
+ * @link jvm/src/jvmutil.c jvm.c@endlink
+ *
+ * @link jvm/src/manifest.c manifest.c@endlink
+ *
+ * @link jvm/src/stdio.c stdio.c@endlink
+ *
+ * @link jvm/src/timeslice.c timeslice.c@endlink
+ *
+ * @link jvm/src/tmparea.c tmparea.c@endlink
+ *
+ * In order to separate the structure packing demands of
+ * <b><code>typedef struct {} ClassFile</code></b>, the
+ * following files will @e not have their prototypes
+ * defined here, even though they are utility functions:
+ *
+ * @link jvm/src/nts.c nts.c@endlink
+ *
+ * @link jvm/src/unicode.c unicode.c@endlink
+ *
+ * @link jvm/src/utf.c utf.c@endlink
+ *
+ *
+ * @section Control
+ *
+ * \$URL: https://svn.apache.org/path/name/util.h $ \$Id: util.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(util, h, "$URL: https://svn.apache.org/path/name/util.h $ $Id: util.h 0 09/28/2005 dlydick $");
+
+
+/* Prototypes for functions in 'bytegames.c' */
+extern rushort bytegames_getrs2(rushort *ptr2);
+extern ruint bytegames_getri4(ruint *ptr4);
+extern rulong bytegames_getrl8(rulong *ptr8);
+
+extern rvoid bytegames_putrs2(rushort *ptr2, rushort val2);
+extern rvoid bytegames_putri4(ruint *ptr4, ruint val4);
+extern rvoid bytegames_putrl8(rulong *ptr8, rulong val8);
+
+extern rushort bytegames_swap2(rushort val);
+extern ruint bytegames_swap4(ruint val);
+
+extern rulong bytegames_swap8(rulong val);
+extern rulong bytegames_mix8(rulong val);
+
+extern jlong bytegames_combine_jlong(jint msword, jint lsword);
+extern jdouble bytegames_combine_jdouble(jint msword, jint lsword);
+
+extern rvoid bytegames_split_jlong(jlong splitlong,
+ jint *msword,
+ jint *lsword);
+extern rvoid bytegames_split_jdouble(jdouble splitdouble,
+ jint *msword,
+ jint *lsword);
+/*!
+ * @todo Make sure GETRI4() works with -m64 compilations (64-bit ptrs)
+ *
+ * @todo Make sure GETRL8() works with -m64 compilations (64-bit ptrs)
+ *
+ *
+ * @internal See @link jvm/src/arch.h arch.h@endlink for the
+ * origin of architecture-specific @c @b \#define's as used below:
+ *
+ */
+#ifdef ARCH_ODD_ADDRESS_SIGSEGV
+#define GETRS2(ptr) bytegames_getrs2(ptr)
+#define GETRI4(ptr) bytegames_getri4(ptr)
+#define GETRL8(ptr) bytegames_getrl8(ptr)
+#else
+#ifdef ARCH_BIG_ENDIAN
+#define GETRS2(ptr) (*(signed rushort *) ptr)
+#define GETRI4(ptr) (*(signed ruint *) ptr)
+#define GETRL8(ptr) (*(signed rulong *) ptr)
+#else
+#define GETRS2(ptr) bytegames_getrs2(ptr)
+#define GETRI4(ptr) bytegames_getri4(ptr)
+#define GETRL8(ptr) bytegames_getrl8(ptr)
+#endif
+#endif
+
+
+#ifdef ARCH_LITTLE_ENDIAN
+
+#define MACHINE_JSHORT_SWAP(rsval) rsval = bytegames_swap2(rsval)
+#define MACHINE_JINT_SWAP(rival) rival = bytegames_swap4(rival)
+#define MACHINE_JLONG_SWAP(rlval) rlval = bytegames_swap8(rlval)
+#define MACHINE_JLONG_MIX(rlval) rlval = bytegames_mix8(rlval)
+
+#define MACHINE_JSHORT_SWAP_PTR(prsval) *prsval = \
+ bytegames_swap2(*prsval)
+#define MACHINE_JINT_SWAP_PTR(prival) *prival = \
+ bytegames_swap4(*prival)
+#define MACHINE_JLONG_SWAP_PTR(prlval) *prlval = \
+ bytegames_swap8(*prlval)
+#define MACHINE_JLONG_MIX_PTR(prlval) *prlval = \
+ bytegames_mix8(*prlval)
+
+#else
+
+/*!
+ * @internal Big endian architectures do not need to swap anything
+ * since the JVM spec declares its (short) and (int) structures
+ * as big endian.
+ *
+ */
+
+#define MACHINE_JSHORT_SWAP(p1)
+#define MACHINE_JINT_SWAP(p1)
+#define MACHINE_JLONG_SWAP(p1)
+#define MACHINE_JLONG_MIX(p1)
+
+#define MACHINE_JSHORT_SWAP_PTR(p1)
+#define MACHINE_JLONG_SWAP_PTR(p1)
+#define MACHINE_JLONG_MIX_PTR(p1)
+
+#endif
+
+
+/* Prototypes for functions in 'stdio.c' */
+
+#ifndef I_AM_STDIO_C
+extern rvoid sysDbgMsg(jvm_debug_level_enum dml,
+ rchar *fn,
+ rchar *fmt,
+ ...);
+extern rvoid sysErrMsg(rchar *fn, rchar *fmt, ...);
+extern rvoid sysErrMsgBfrFormat(rchar *bfr, rchar *fn, rchar *fmt, ...);
+extern rvoid sprintfLocal(rchar *bfr, rchar *fmt, ...);
+extern rvoid fprintfLocalStderr(rchar *fmt, ...);
+extern rvoid fprintfLocalStdout(rchar *fmt, ...);
+#endif
+
+/*!
+ * @internal <b>DO NOT</b> (!) define prototypes for
+ * _printfLocal() or _fprintfLocal() or _sprintfLocal().
+ * They are meant to promote use of printfLocal() and
+ * fprintfLocal() and sprintfLocal() instead, so let
+ * compile warnings help.
+ *
+ */
+
+
+/* Prototypes for functions in 'argv.c' */
+
+extern rvoid argv_init(int argc, char **argv, char **envp);
+
+extern rvoid argv_shutdown(rvoid);
+
+extern rvoid argv_versionmsg(rvoid);
+
+extern rvoid argv_copyrightmsg(rvoid);
+
+extern rvoid argv_licensemsg(rvoid);
+
+extern rvoid argv_helpmsg(rvoid);
+
+extern rvoid argv_showmsg(rvoid);
+
+
+/* Prototypes for small utility functions in 'jvmutil.c' */
+
+extern rvoid jvmutil_set_dml(jvm_debug_level_enum level);
+extern jvm_debug_level_enum jvmutil_get_dml(rvoid);
+
+extern rvoid jvmutil_print_stack(jvm_thread_index thridx,
+ rchar *pheader);
+extern rvoid jvmutil_print_stack_details(jvm_thread_index thridx,
+ rchar *pheader);
+extern rvoid jvmutil_print_stack_locals(jvm_thread_index thridx,
+ rchar *pheader);
+extern rvoid jvmutil_print_error_stack(jvm_thread_index thridx);
+extern rvoid jvmutil_print_exception_stack(jvm_thread_index thridx);
+
+
+/* Prototypes for functions in 'manifest.c' */
+
+extern rchar *manifest_get_main(rchar *mnfname);
+
+
+/* Prototypes for functions in 'timeslice.c' */
+
+extern rvoid timeslice_shutdown(rvoid);
+extern jlong timeslice_get_thread_sleeptime(jvm_thread_index thridx);
+extern void *timeslice_run(void *dummy);
+extern rvoid timeslice_init(rvoid);
+
+
+/* Prototypes for functions in 'tmparea.c' */
+
+extern rvoid tmparea_init(char **argv);
+extern const rchar *tmparea_get(rvoid);
+extern rvoid tmparea_shutdown(rvoid);
+
+#endif /* _util_h_defined_ */
+
+
+/* EOF */