#include <stdarg.h>
#include <stdio.h>
#include <string.h>
-#ifdef HANDLE_SEGV
-#include <signal.h>
-#endif
#pragma implementation "java-array.h"
#include <cni.h>
#include <jvm.h>
+#include <java-signal.h>
#include <java/lang/Class.h>
#include <java/lang/Runtime.h>
#include <java/lang/ThreadGroup.h>
#include <java/lang/FirstThread.h>
#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/ArithmeticException.h>
#include <java/lang/ClassFormatError.h>
#include <java/lang/ClassCastException.h>
#include <java/lang/NegativeArraySizeException.h>
#include <java/lang/reflect/Modifier.h>
#include <java/io/PrintStream.h>
+#ifdef USE_LTDL
+#include <ltdl.h>
+#endif
+
#define ObjectClass _CL_Q34java4lang6Object
extern java::lang::Class ObjectClass;
\f
+#ifdef HANDLE_SEGV
+static java::lang::NullPointerException *nullp;
+SIGNAL_HANDLER (catch_segv)
+{
+ MAKE_THROW_FRAME;
+ _Jv_Throw (nullp);
+}
+#endif
+
+static java::lang::ArithmeticException *arithexception;
+
+#ifdef HANDLE_FPE
+SIGNAL_HANDLER (catch_fpe)
+{
+#ifdef HANDLE_DIVIDE_OVERFLOW
+ HANDLE_DIVIDE_OVERFLOW;
+#else
+ MAKE_THROW_FRAME;
+#endif
+ _Jv_Throw (arithexception);
+}
+#endif
+
+\f
+
jboolean
_Jv_equalUtf8Consts (Utf8Const* a, Utf8Const *b)
{
}
/* True iff A is equal to STR.
- HASH is STR->hashCode().
+ HASH is STR->hashCode().
*/
jboolean
return (m);
}
+_Jv_Utf8Const *
+_Jv_makeUtf8Const (jstring string)
+{
+ jint hash = string->hashCode ();
+ jint len = _Jv_GetStringUTFLength (string);
+
+ Utf8Const* m = (Utf8Const*)
+ _Jv_AllocBytesChecked (sizeof(Utf8Const) + len + 1);
+
+ m->hash = hash;
+ m->length = len;
+
+ _Jv_GetStringUTFRegion (string, 0, string->length (), m->data);
+ m->data[len] = 0;
+
+ return m;
+}
+
\f
#ifdef DEBUG
JvThrow (no_memory);
size_t size = count * sizeof (jobject) + sizeof (__JArray);
- jclass clas = _Jv_FindArrayClass (elementClass);
+
+ // FIXME: second argument should be "current loader" //
+ jclass clas = _Jv_FindArrayClass (elementClass, 0);
+
jobjectArray obj = (jobjectArray) _Jv_AllocArray (size);
if (! obj)
JvThrow (no_memory);
arr->length = count;
// Note that we assume we are given zeroed memory by the allocator.
- jclass klass = _Jv_FindArrayClass (eltype);
+ jclass klass = _Jv_FindArrayClass (eltype, 0);
// Set the vtbl last to avoid problems if the GC happens during the
// window in this function between the allocation and this
// assignment.
\f
-#ifdef HANDLE_SEGV
-
-static java::lang::NullPointerException *nullp;
-
-static void
-catch_segv (int)
-{
- // Don't run `new' in a signal handler, so we always throw the same
- // null pointer exception.
- _Jv_Throw (nullp);
-}
-
-#endif /* HANDLE_SEGV */
-
class _Jv_PrimClass : public java::lang::Class
{
public:
;
_Jv_Utf8Const *name = _Jv_makeUtf8Const (&sig[1], i - 1);
return _Jv_FindClass (name, loader);
+
}
case '[':
- return _Jv_FindArrayClass (_Jv_FindClassFromSignature (&sig[1], loader));
+ return _Jv_FindArrayClass (_Jv_FindClassFromSignature (&sig[1], loader),
+ loader);
}
JvFail ("couldn't understand class signature");
return NULL; // Placate compiler.
void
JvRunMain (jclass klass, int argc, const char **argv)
{
-#ifdef HANDLE_SEGV
- nullp = new java::lang::NullPointerException ();
-
- struct sigaction act;
- act.sa_handler = catch_segv;
- sigemptyset (&act.sa_mask);
- act.sa_flags = 0;
- sigaction (SIGSEGV, &act, NULL);
+ INIT_SEGV;
+#ifdef HANDLE_FPE
+ INIT_FPE;
+#else
+ arithexception = new java::lang::ArithmeticException
+ (JvNewStringLatin1 ("/ by zero"));
#endif
no_memory = new java::lang::OutOfMemoryError;
+#ifdef USE_LTDL
+ LTDL_SET_PRELOADED_SYMBOLS ();
+#endif
+
arg_vec = JvConvertArgv (argc - 1, argv + 1);
main_group = new java::lang::ThreadGroup (23);
main_thread = new java::lang::FirstThread (main_group, klass, arg_vec);
java::lang::Runtime::getRuntime ()->exit (0);
}
+void
+_Jv_RunMain (const char *class_name, int argc, const char **argv)
+{
+ INIT_SEGV;
+#ifdef HANDLE_FPE
+ INIT_FPE;
+#else
+ arithexception = new java::lang::ArithmeticException
+ (JvNewStringLatin1 ("/ by zero"));
+#endif
+
+ no_memory = new java::lang::OutOfMemoryError;
+
+#ifdef USE_LTDL
+ LTDL_SET_PRELOADED_SYMBOLS ();
+#endif
+
+ arg_vec = JvConvertArgv (argc - 1, argv + 1);
+ main_group = new java::lang::ThreadGroup (23);
+ main_thread = new java::lang::FirstThread (main_group,
+ JvNewStringLatin1 (class_name),
+ arg_vec);
+ main_thread->start();
+ _Jv_ThreadWait ();
+
+ java::lang::Runtime::getRuntime ()->exit (0);
+}
+
+
\f
void *
{
return free (ptr);
}
+
+\f
+
+// In theory, these routines can be #ifdef'd away on machines which
+// support divide overflow signals. However, we never know if some
+// code might have been compiled with "-fuse-divide-subroutine", so we
+// always include them in libgcj.
+
+jint
+_Jv_divI (jint dividend, jint divisor)
+{
+ if (divisor == 0)
+ _Jv_Throw (arithexception);
+
+ if (dividend == (jint) 0x80000000L && divisor == -1)
+ return dividend;
+
+ return dividend / divisor;
+}
+
+jint
+_Jv_remI (jint dividend, jint divisor)
+{
+ if (divisor == 0)
+ _Jv_Throw (arithexception);
+
+ if (dividend == (jint) 0x80000000L && divisor == -1)
+ return 0;
+
+ return dividend % divisor;
+}
+
+jlong
+_Jv_divJ (jlong dividend, jlong divisor)
+{
+ if (divisor == 0)
+ _Jv_Throw (arithexception);
+
+ if (dividend == (jlong) 0x8000000000000000LL && divisor == -1)
+ return dividend;
+
+ return dividend / divisor;
+}
+
+jlong
+_Jv_remJ (jlong dividend, jlong divisor)
+{
+ if (divisor == 0)
+ _Jv_Throw (arithexception);
+
+ if (dividend == (jlong) 0x8000000000000000LL && divisor == -1)
+ return 0;
+
+ return dividend % divisor;
+}
+
+
+
+
+
+
+