[ecj] Implement VMStackWalker.getClassContext()

Gary Benson gbenson@redhat.com
Thu Nov 30 18:25:00 GMT 2006


Hi again,

This commit implements VMStackWalker.getClassContext().

Cheers,
Gary
-------------- next part --------------
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 119361)
+++ ChangeLog	(working copy)
@@ -1,3 +1,13 @@
+2006-11-30  Gary Benson  <gbenson@redhat.com>
+
+	* include/java-stack.h (GetStackWalkerStack): Declare.
+	* stacktrace.cc (GetStackWalkerStack): New method.
+	* gnu/classpath/natVMStackWalker.cc (getClassContext): Likewise.
+	* gnu/classpath/VMStackWalker.java
+	(getClassContext): Replace stub with native method declaration.
+	(getCallingClass): Remove "throws NotImplementedException".
+	(getCallingClassLoader): Likewise.
+
 2006-11-30  Gary Benson  <gbenson@redhat.com>
 
 	* java/lang/ClassLoader.java: Merged javadoc.
Index: include/java-stack.h
===================================================================
--- include/java-stack.h	(revision 119314)
+++ include/java-stack.h	(working copy)
@@ -139,6 +139,7 @@
   static JArray<jclass> *GetClassContext (jclass checkClass);
   static ClassLoader *GetFirstNonSystemClassLoader (void);
   static jobjectArray GetAccessControlStack ();
+  static JArray<jclass> *GetStackWalkerStack ();
 
   friend jclass _Jv_GetMethodDeclaringClass (jmethodID);
   friend class gnu::classpath::VMStackWalker;
Index: stacktrace.cc
===================================================================
--- stacktrace.cc	(revision 119314)
+++ stacktrace.cc	(working copy)
@@ -21,10 +21,12 @@
 #include <java/lang/Boolean.h>
 #include <java/lang/Class.h>
 #include <java/lang/Long.h>
+#include <java/lang/reflect/Method.h>
 #include <java/security/AccessController.h>
 #include <java/util/ArrayList.h>
 #include <java/util/IdentityHashMap.h>
 #include <gnu/classpath/jdwp/Jdwp.h>
+#include <gnu/classpath/VMStackWalker.h>
 #include <gnu/java/lang/MainThread.h>
 #include <gnu/gcj/runtime/NameFinder.h>
 #include <gnu/gcj/runtime/StringBuffer.h>
@@ -631,3 +633,76 @@
   
   return result;
 }
+
+JArray<jclass> *
+_Jv_StackTrace::GetStackWalkerStack ()
+{
+  int trace_size = 100;
+  _Jv_StackFrame frames[trace_size];
+  _Jv_UnwindState state (trace_size);
+  state.frames = (_Jv_StackFrame *) &frames;
+
+  UpdateNCodeMap ();
+  _Unwind_Backtrace (UnwindTraceFn, &state);
+
+  int num_frames = 0, start_frame = -1;
+  enum
+    {
+      VMSW_GETCLASSCONTEXT,
+      JLRM_INVOKE_OR_USER_FN,
+      USER_FN
+    }
+  expect = VMSW_GETCLASSCONTEXT;
+  for (int i = 0; i < state.pos; i++)
+    {
+      _Jv_StackFrame *frame = &state.frames[i];
+      FillInFrameInfo (frame);
+      if (!frame->klass || !frame->meth)
+	continue;
+
+      switch (expect)
+	{
+	case VMSW_GETCLASSCONTEXT:
+	  JvAssert (
+	    frame->klass == &::gnu::classpath::VMStackWalker::class$
+	    && strcmp (frame->meth->name->chars(), "getClassContext") == 0);
+	  expect = JLRM_INVOKE_OR_USER_FN;
+	  break;
+
+	case JLRM_INVOKE_OR_USER_FN:
+	  if (frame->klass != &::java::lang::reflect::Method::class$
+	      || strcmp (frame->meth->name->chars(), "invoke") != 0)
+	    start_frame = i;
+	  expect = USER_FN;
+	  break;
+
+	case USER_FN:
+	  if (start_frame == -1)
+	    start_frame = i;
+	  break;
+	}
+
+      if (start_frame != -1)
+	{
+	  if (frame->klass == &::gnu::java::lang::MainThread::class$)
+	    break;
+	  num_frames++;
+	}
+    }
+  JvAssert (num_frames > 0 && start_frame > 0);
+
+  JArray<jclass> *result = (JArray<jclass> *)
+    _Jv_NewObjectArray (num_frames, &::java::lang::Class::class$, NULL);
+  jclass *c = elements (result);
+
+  for (int i = start_frame, j = 0; i < state.pos && j < num_frames; i++)
+    {
+      _Jv_StackFrame *frame = &state.frames[i];
+      if (!frame->klass || !frame->meth)
+	continue;
+      c[j] = frame->klass;
+      j++;
+    }
+ 
+  return result;
+}
Index: gnu/classpath/natVMStackWalker.cc
===================================================================
--- gnu/classpath/natVMStackWalker.cc	(revision 119314)
+++ gnu/classpath/natVMStackWalker.cc	(working copy)
@@ -18,6 +18,13 @@
 #include <gnu/gcj/RawData.h>
 #include <java/lang/ClassLoader.h>
 
+JArray<jclass> *
+gnu::classpath::VMStackWalker::getClassContext(void)
+{
+  // FIXME: Security check here?
+  return _Jv_StackTrace::GetStackWalkerStack ();
+}
+
 jclass
 gnu::classpath::VMStackWalker::getCallingClass(::gnu::gcj::RawData *pc)
 {
Index: gnu/classpath/VMStackWalker.java
===================================================================
--- gnu/classpath/VMStackWalker.java	(revision 119314)
+++ gnu/classpath/VMStackWalker.java	(working copy)
@@ -51,6 +51,7 @@
  * @author Eric Blake <ebb9@email.byu.edu>
  * @author Archie Cobbs
  * @author Andrew Haley <aph@redhat.com>
+ * @author Gary Benson <gbenson@redhat.com>
  */
 public final class VMStackWalker
 {
@@ -68,11 +69,7 @@
    *
    * @return an array of the declaring classes of each stack frame
    */
-  public static Class[] getClassContext()
-    throws NotImplementedException
-  {
-    return null;
-  }
+  public static native Class[] getClassContext();
 
   /**
    * Get the class associated with the method invoking the method
@@ -89,7 +86,6 @@
    * stack, so is therefore more efficient.
    */
   public static Class getCallingClass()
-    throws NotImplementedException
   {
     Class[] ctx = getClassContext();
     if (ctx.length < 3)
@@ -121,7 +117,6 @@
    * unwind the stack, so is therefore more efficient.
    */
   public static ClassLoader getCallingClassLoader()
-    throws NotImplementedException
   {
     Class[] ctx = getClassContext();
     if (ctx.length < 3)


More information about the Java-patches mailing list