I propose adding a new class that may be optionally implemented by the VM, gnu.classpath.VMStackBrowser. I say that it is "optional" because I have here a reference implementation for it that uses the existing gnu.classpath.VMStackWalker to do all the work:
/* VMStackBrowser.java -- Reference implementation of OPTIONAL VM hooks for stack access. [The Classpath copyright notice can go here] */ package gnu.classpath; /** * This optional class provides access to the classes on the Java stack. * Use this class to explore the stack. It is sometimes necessary to * find out the current context class loader, and other things like that. * <P> * This reference implementation works on top of the mandatory VMStackWalker * class. So you can leave it completely alone if you want to. * You may be able to improve your VM's efficiency by implementing * VMStackBrowser yourself. It's your choice. */ public final class VMStackBrowser { /** * Internal storage -- the class context returned by VMStackWalker. * */ private Class[] context; /** * Where are we in the array [EMAIL PROTECTED] #context}[]? */ private int position; /** * Create a new VMStackBrowser, rooted at the caller's current stack frame. * The only exception is if the caller is a method in * java.lang.reflect.Method. Since we can not tell those methods apart (all * we know is that the class java.lang.reflect.Method was at the top of the * frame), we will skip past it in order to present an interface just like * that of [EMAIL PROTECTED] VMStackWalker}. * <p> * If your VM has stacks that can be moved by the garbage collector, * you may have to turn off GC temporarily here. */ VMStackBrowser() { context = VMStackWalker.getClassContext(); resetPosition(); } /** Set our position back to the newly-created state, using the same stack * trace we started with. */ public void resetPosition () { // context[0] is us. Skip it. position = 1; /* If we were invoked by JNI, then we might be past the top of the stack. */ if (position < context.length) return; /* If we were invoked by java.lang.reflect.Method.invoke, then pop up one * more, for compatibility with [EMAIL PROTECTED] VMStackWalker#getClassContext}'s * behaviour. */ if (context[position] == java.lang.reflect.Method.class) ++position; } /** * @return the class at the current position in our walk; otherwise, * <code>null</code> if we're past the top of the stack. */ public Class getCurrentClass() { if (position < context.length) return context[position]; else return null; } /** Can we go up further and still be at a valid stack location? */ public boolean hasMoreFrames() { return (position + 1 < context.length); } /** Go up a frame. */ public void up() { ++position; } /* If your VM has stacks that can be moved by the garbage collector, * such that the [EMAIL PROTECTED] VMStackBrowser} constructor turns off garbage * collection, then turn GC back on again here. */ public void release () {} } Here is an example of how it could be used by java.lang.SecurityManager; note that I have not attempted to compile this code, so there may be a typo or two: --- java/lang/SecurityManager.java 7 Jan 2005 15:08:23 -0000 1.26 +++ java/lang/SecurityManager.java 16 Jan 2005 05:45:12 -0000 @@ -39,6 +39,7 @@ package java.lang; import gnu.classpath.VMStackWalker; +import gnu.classpath.VMStackBrowser; import java.awt.AWTPermission; import java.io.File; @@ -242,10 +243,14 @@ */ protected int classDepth(String className) { - Class[] c = getClassContext(); - for (int i = 0; i < c.length; i++) - if (className.equals(c[i].getName())) - return i; + VMStackBrowser b = new VMStackBrowser(); + while (b.hasMoreFrames()) + { + if (className.equals(c[i].getName())) + b.release(); + return i; + } + b.release(); return -1; } --Steven Augart -- Jikes RVM, a free, open source, Virtual Machine: http://oss.software.ibm.com/jikesrvm _______________________________________________ Classpath mailing list Classpath@gnu.org http://lists.gnu.org/mailman/listinfo/classpath