]> gcc.gnu.org Git - gcc.git/blobdiff - libjava/prims.cc
re GNATS libgcj/40 (wait(timeout) wrongly throws IllegalMonitorState exception)
[gcc.git] / libjava / prims.cc
index 265e281dcb16e959d8bf15a123850036ae432425..3b0863c2d773e7ce6626e9fb75dfca2d4598649b 100644 (file)
@@ -14,14 +14,12 @@ details.  */
 #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>
@@ -30,6 +28,7 @@ details.  */
 #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>
@@ -40,6 +39,10 @@ details.  */
 #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;
 
@@ -52,6 +55,31 @@ static java::lang::OutOfMemoryError *no_memory;
 
 \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)
 {
@@ -74,7 +102,7 @@ _Jv_equalUtf8Consts (Utf8Const* a, Utf8Const *b)
 }
 
 /* True iff A is equal to STR.
-   HASH is STR->hashCode().
+   HASH is STR->hashCode().  
 */
 
 jboolean
@@ -152,6 +180,24 @@ _Jv_makeUtf8Const (char* s, int len)
   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
@@ -270,7 +316,10 @@ _Jv_NewObjectArray (jsize count, jclass elementClass, jobject init)
     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);
@@ -310,7 +359,7 @@ _Jv_NewPrimArray (jclass eltype, jint count)
   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.
@@ -426,20 +475,6 @@ _Jv_NewMultiArray (jclass array_type, jint dimensions, ...)
 
 \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:
@@ -517,9 +552,11 @@ _Jv_FindClassFromSignature (char *sig, java::lang::ClassLoader *loader)
          ;
        _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.
@@ -560,18 +597,20 @@ static java::lang::Thread *main_thread;
 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);
@@ -582,6 +621,35 @@ JvRunMain (jclass klass, int argc, const char **argv)
   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 *
@@ -600,3 +668,65 @@ _Jv_Free (void* ptr)
 {
   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;
+}
+
+
+
+
+
+
+
This page took 0.032105 seconds and 5 git commands to generate.