aboutsummaryrefslogtreecommitdiff
path: root/libjava
diff options
context:
space:
mode:
author(no author) <(no author)@138bc75d-0d04-0410-961f-82ee72b054a4>2002-12-17 20:51:25 +0000
committer(no author) <(no author)@138bc75d-0d04-0410-961f-82ee72b054a4>2002-12-17 20:51:25 +0000
commit9518dc53d4fc99e96a63e96d5ed7ce9c2873e6dd (patch)
tree38a7c91378083770a54c3bd0ab2e060d50ee3ecd /libjava
parent01f21078c91a6692a78c87585184038a9b8daec0 (diff)
This commit was manufactured by cvs2svn to create branch
'tree-ssa-20020619-branch'. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/tree-ssa-20020619-branch@60220 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava')
-rw-r--r--libjava/gnu/gcj/runtime/natStackTrace.cc197
-rw-r--r--libjava/gnu/gcj/runtime/natVMClassLoader.cc67
-rw-r--r--libjava/java/lang/natVMSecurityManager.cc54
-rw-r--r--libjava/java/util/natResourceBundle.cc32
-rw-r--r--libjava/testsuite/libjava.lang/override.java19
-rw-r--r--libjava/testsuite/libjava.lang/override.out2
-rw-r--r--libjava/testsuite/libjava.lang/pr8823.java24
-rw-r--r--libjava/testsuite/libjava.lang/pr8823.out1
8 files changed, 396 insertions, 0 deletions
diff --git a/libjava/gnu/gcj/runtime/natStackTrace.cc b/libjava/gnu/gcj/runtime/natStackTrace.cc
new file mode 100644
index 00000000000..e977f356638
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/natStackTrace.cc
@@ -0,0 +1,197 @@
+// natStackTrace.cc - native helper methods for Throwable
+
+/* Copyright (C) 2000, 2002 Free Software Foundation, Inc
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+/**
+ * @author Andrew Haley <aph@cygnus.com>
+ * @author Mark Wielaard <mark@klomp.org>
+ *
+ * Native helper methods for VM specific Throwable support.
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <jvm.h>
+#include <gcj/cni.h>
+#include <gnu/gcj/RawData.h>
+#include <java/lang/Object.h>
+#include <java-threads.h>
+#include <gnu/gcj/runtime/MethodRef.h>
+#include <gnu/gcj/runtime/StackTrace.h>
+#include <java/lang/Thread.h>
+#include <java-interp.h>
+#include <java/util/IdentityHashMap.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+
+#include <unistd.h>
+
+#ifdef HAVE_EXECINFO_H
+#include <execinfo.h>
+#endif
+
+#include <unwind.h>
+
+
+// Fill in this stack trace with MAXLEN elements starting at offset.
+void
+gnu::gcj::runtime::StackTrace::fillInStackTrace (jint maxlen, jint offset)
+{
+#ifdef HAVE_BACKTRACE
+ offset += 1;
+ void *_p[maxlen + offset];
+ len = backtrace (_p, maxlen + offset) - offset;
+ void **p = _p + offset;
+ _Jv_frame_info *frame;
+ if (len > 0)
+ {
+#ifdef INTERPRETER
+ extern void _Jv_StartOfInterpreter (void);
+ extern void _Jv_EndOfInterpreter (void);
+
+ java::lang::Thread *thread = java::lang::Thread::currentThread();
+ _Jv_MethodChain *interp_frame
+ = (thread ? reinterpret_cast<_Jv_MethodChain *> (thread->interp_frame)
+ : NULL);
+#endif // INTERPRETER
+
+ frame = (_Jv_frame_info *) _Jv_Malloc (len * sizeof (_Jv_frame_info));
+ for (int n = 0; n < len; n++)
+ {
+ frame[n].addr = p[n];
+#ifdef INTERPRETER
+ if (p[n] >= &_Jv_StartOfInterpreter && p[n] <= &_Jv_EndOfInterpreter)
+ {
+ frame[n].interp = (void *) interp_frame->self;
+ interp_frame = interp_frame->next;
+ }
+ else
+ frame[n].interp = 0;
+#endif // INTERPRETER
+ }
+ }
+ else
+ frame = NULL;
+
+ addrs = reinterpret_cast<gnu::gcj::RawData *> (frame);
+#else // HAVE_BACKTRACE
+ (void)maxlen;
+ (void)offset;
+#endif // HAVE_BACKTRACE
+}
+
+/* Obtain the next power-of-2 of some integer. */
+static inline jint
+nextpowerof2 (jint n)
+{
+ n |= (n >> 1);
+ n |= (n >> 2);
+ n |= (n >> 4);
+ n |= (n >> 8);
+ n |= (n >> 16);
+ return n+1;
+}
+
+#define GET_FRAME(N) \
+({ \
+ if ((N) >= len) \
+ fillInStackTrace (nextpowerof2 (N), 1); \
+ if ((N) < 0 || (N) >= len) \
+ throw new ::java::lang::ArrayIndexOutOfBoundsException (); \
+ \
+ _Jv_frame_info *frame = (_Jv_frame_info *)addrs; \
+ &frame[N]; \
+})
+
+gnu::gcj::runtime::MethodRef *
+gnu::gcj::runtime::StackTrace::getCompiledMethodRef (gnu::gcj::RawData *addr)
+{
+ void *p = _Unwind_FindEnclosingFunction (addr);
+ return gnu::gcj::runtime::StackTrace
+ ::methodAtAddress ((gnu::gcj::RawData *)p);
+}
+
+java::lang::Class *
+gnu::gcj::runtime::StackTrace::classAt (jint n)
+{
+ _Jv_frame_info *frame = GET_FRAME (n);
+
+#ifdef INTERPRETER
+ if (frame->interp)
+ {
+ _Jv_InterpMethod *meth
+ = reinterpret_cast<_Jv_InterpMethod *> (frame->interp);
+ return meth->defining_class;
+ }
+#endif // INTERPRETER
+
+ gnu::gcj::runtime::MethodRef *ref
+ = getCompiledMethodRef ((gnu::gcj::RawData *)frame->addr);
+ if (ref)
+ return ref->klass;
+ else
+ return NULL;
+}
+
+java::lang::String*
+gnu::gcj::runtime::StackTrace::methodAt (jint n)
+{
+ _Jv_frame_info *frame = GET_FRAME (n);
+ _Jv_Method *meth = NULL;
+
+#ifdef INTERPRETER
+ if (frame->interp)
+ {
+ meth
+ = reinterpret_cast<_Jv_InterpMethod *> (frame->interp)
+ ->get_method();
+ }
+#endif // INTERPRETER
+
+ if (! meth)
+ {
+ gnu::gcj::runtime::MethodRef *ref
+ = getCompiledMethodRef ((gnu::gcj::RawData *)frame->addr);
+ if (ref)
+ meth = (_Jv_Method *)ref->method;
+ }
+
+ return meth
+ ? _Jv_NewStringUtf8Const (meth->name)
+ : NULL ;
+}
+
+void
+gnu::gcj::runtime::StackTrace::update(void)
+{
+ jclass klass;
+
+ while ((klass = _Jv_PopClass ()))
+ {
+ for (int i=0; i<klass->method_count; i++)
+ {
+ JvSynchronize sync (map);
+ _Jv_Method *meth = &(klass->methods[i]);
+ if (meth->ncode) // i.e. if p is not abstract
+ {
+ gnu::gcj::runtime::MethodRef *ref
+ = new gnu::gcj::runtime::MethodRef
+ ((gnu::gcj::RawData *)meth, klass);
+ map->put ((java::lang::Object*)(meth->ncode), ref);
+ }
+ }
+ }
+}
+
+
diff --git a/libjava/gnu/gcj/runtime/natVMClassLoader.cc b/libjava/gnu/gcj/runtime/natVMClassLoader.cc
new file mode 100644
index 00000000000..33b63d6759a
--- /dev/null
+++ b/libjava/gnu/gcj/runtime/natVMClassLoader.cc
@@ -0,0 +1,67 @@
+// Native code for VMClassLoader
+
+/* Copyright (C) 2002 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <gnu/gcj/runtime/VMClassLoader.h>
+#include <java/lang/Class.h>
+#include <java/lang/StringBuffer.h>
+#include <java/net/URLClassLoader.h>
+#include <java/lang/Runtime.h>
+
+jclass
+gnu::gcj::runtime::VMClassLoader::findClass (jstring name)
+{
+ _Jv_Utf8Const *name_u = _Jv_makeUtf8Const (name);
+ jclass klass = _Jv_FindClassInCache (name_u, 0);
+
+ if (! klass)
+ {
+ // Turn `gnu.pkg.quux' into `lib-gnu-pkg-quux'. Then search for
+ // a module named (eg, on Linux) `lib-gnu-pkg-quux.so', followed
+ // by `lib-gnu-pkg.so' and `lib-gnu.so'. If loading one of
+ // these causes the class to appear in the cache, then use it.
+ java::lang::StringBuffer *sb = new java::lang::StringBuffer (JvNewStringLatin1("lib-"));
+ // Skip inner classes
+ jstring cn;
+ jint ci = name->indexOf('$');
+ if (ci == -1)
+ cn = name;
+ else
+ cn = name->substring (0, ci);
+ jstring so_base_name = (sb->append (cn)->toString ())->replace ('.', '-');
+
+ // Compare against `3' because that is the length of "lib".
+ while (! klass && so_base_name && so_base_name->length() > 3)
+ {
+ using namespace ::java::lang;
+ Runtime *rt = Runtime::getRuntime();
+ jboolean loaded = rt->loadLibraryInternal (so_base_name);
+
+ jint nd = so_base_name->lastIndexOf ('-');
+ if (nd == -1)
+ so_base_name = NULL;
+ else
+ so_base_name = so_base_name->substring (0, nd);
+
+ if (loaded)
+ klass = _Jv_FindClassInCache (name_u, 0);
+ }
+ }
+
+ // Now try loading using the interpreter.
+ if (! klass)
+ klass = java::net::URLClassLoader::findClass (name);
+
+ return klass;
+}
diff --git a/libjava/java/lang/natVMSecurityManager.cc b/libjava/java/lang/natVMSecurityManager.cc
new file mode 100644
index 00000000000..7b88e8a4a8c
--- /dev/null
+++ b/libjava/java/lang/natVMSecurityManager.cc
@@ -0,0 +1,54 @@
+/* Copyright (C) 2002 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+// Written by Tom Tromey <tromey@redhat.com>
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/lang/VMSecurityManager.h>
+#include <java/lang/SecurityManager.h>
+#include <java/lang/ClassLoader.h>
+#include <java/lang/Class.h>
+#include <gnu/gcj/runtime/StackTrace.h>
+
+JArray<jclass> *
+java::lang::VMSecurityManager::getClassContext ()
+{
+ JArray<jclass> *result = NULL;
+ gnu::gcj::runtime::StackTrace *t = new gnu::gcj::runtime::StackTrace();
+ if (t)
+ {
+ int maxlen = t->length();
+
+ int len = 0;
+ while (len < maxlen)
+ {
+ jclass klass = t->classAt(len);
+ if (klass != NULL && klass != &java::lang::VMSecurityManager::class$
+ && klass != &java::lang::SecurityManager::class$)
+ ++len;
+ }
+
+ result =
+ (JArray<jclass> *) _Jv_NewObjectArray (len, &java::lang::Class::class$,
+ NULL);
+
+ len = 0;
+ while (len < maxlen)
+ {
+ jclass klass = t->classAt(len);
+ if (klass != NULL && klass != &java::lang::VMSecurityManager::class$
+ && klass != &java::lang::SecurityManager::class$)
+ elements(result)[len++] = klass;
+ }
+ }
+
+ return result;
+}
diff --git a/libjava/java/util/natResourceBundle.cc b/libjava/java/util/natResourceBundle.cc
new file mode 100644
index 00000000000..21a9565c996
--- /dev/null
+++ b/libjava/java/util/natResourceBundle.cc
@@ -0,0 +1,32 @@
+/* Copyright (C) 2002 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+// Written by Tom Tromey <tromey@redhat.com>
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/util/ResourceBundle.h>
+#include <java/lang/SecurityManager.h>
+#include <java/lang/ClassLoader.h>
+#include <java/lang/Class.h>
+#include <gnu/gcj/runtime/StackTrace.h>
+
+java::lang::ClassLoader *
+java::util::ResourceBundle::getCallingClassLoader ()
+{
+ gnu::gcj::runtime::StackTrace *t = new gnu::gcj::runtime::StackTrace(6);
+ for (int i = 3; i < 6; ++i)
+ {
+ jclass klass = t->classAt(i);
+ if (klass != NULL)
+ return klass->getClassLoaderInternal();
+ }
+ return NULL;
+}
diff --git a/libjava/testsuite/libjava.lang/override.java b/libjava/testsuite/libjava.lang/override.java
new file mode 100644
index 00000000000..94bb09cfc0d
--- /dev/null
+++ b/libjava/testsuite/libjava.lang/override.java
@@ -0,0 +1,19 @@
+// Regression test that overrides a virtual method with a final one.
+
+class override1
+{
+ public int x1 () { return 3; }
+}
+
+public class override extends override1
+{
+ public final int x1() { return 5; }
+ public final int x2() { return 7; }
+
+ public static void main(String[] args)
+ {
+ override z = new override();
+ System.out.println(z.x1());
+ System.out.println(z.x2());
+ }
+}
diff --git a/libjava/testsuite/libjava.lang/override.out b/libjava/testsuite/libjava.lang/override.out
new file mode 100644
index 00000000000..b3172d1242f
--- /dev/null
+++ b/libjava/testsuite/libjava.lang/override.out
@@ -0,0 +1,2 @@
+5
+7
diff --git a/libjava/testsuite/libjava.lang/pr8823.java b/libjava/testsuite/libjava.lang/pr8823.java
new file mode 100644
index 00000000000..3327ddf7a2a
--- /dev/null
+++ b/libjava/testsuite/libjava.lang/pr8823.java
@@ -0,0 +1,24 @@
+interface I
+{
+ public void m();
+}
+
+abstract class A implements I
+{
+ // But doesn't define m()
+}
+
+public class pr8823 extends A // which means it implements I
+{
+ public static void main(String[] args)
+ {
+ // Defining c as either I or C will work.
+ A c = new pr8823();
+ c.m();
+ }
+
+ public void m()
+ {
+ System.out.println("Hello World!");
+ }
+}
diff --git a/libjava/testsuite/libjava.lang/pr8823.out b/libjava/testsuite/libjava.lang/pr8823.out
new file mode 100644
index 00000000000..980a0d5f19a
--- /dev/null
+++ b/libjava/testsuite/libjava.lang/pr8823.out
@@ -0,0 +1 @@
+Hello World!