Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    ***** BEGIN LICENSE BLOCK *****
    * Version: EPL 1.0/GPL 2.0/LGPL 2.1
    *
    * The contents of this file are subject to the Eclipse Public
    * License Version 1.0 (the "License"); you may not use this file
    * except in compliance with the License. You may obtain a copy of
    * the License at http://www.eclipse.org/legal/epl-v10.html
    *
   * Software distributed under the License is distributed on an "AS
   * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
   * implied. See the License for the specific language governing
   * rights and limitations under the License.
   *
   * Copyright (C) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
   * Copyright (C) 2002-2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
   * Copyright (C) 2004 Thomas E Enebo <enebo@acm.org>
   * Copyright (C) 2004-2005 Charles O Nutter <headius@headius.com>
   * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
   * Copyright (C) 2006 Michael Studman <codehaus@michaelstudman.com>
   * Copyright (C) 2006 Miguel Covarrubias <mlcovarrubias@gmail.com>
   * Copyright (C) 2007 William N Dortch <bill.dortch@gmail.com>
   *
   * Alternatively, the contents of this file may be used under the terms of
   * either of the GNU General Public License Version 2 or later (the "GPL"),
   * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
   * in which case the provisions of the GPL or the LGPL are applicable instead
   * of those above. If you wish to allow use of your version of this file only
   * under the terms of either the GPL or the LGPL, and not to allow others to
   * use your version of this file under the terms of the EPL, indicate your
   * decision by deleting the provisions above and replace them with the notice
   * and other provisions required by the GPL or the LGPL. If you do not delete
   * the provisions above, a recipient may use your version of this file under
   * the terms of any one of the EPL, the GPL or the LGPL.
   ***** END LICENSE BLOCK *****/
  package org.jruby.runtime;
  
  import java.util.Arrays;
  import java.util.List;
  import java.util.Locale;
  import java.util.Set;
  
  import org.jruby.Ruby;
  
  public final class ThreadContext {
  
      private static final Logger LOG = LoggerFactory.getLogger("ThreadContext");
  
      public static ThreadContext newContext(Ruby runtime) {
          ThreadContext context = new ThreadContext(runtime);
          return context;
      }
      
      private final static int INITIAL_SIZE = 10;
      private final static int INITIAL_FRAMES_SIZE = 10;
    
    
The number of calls after which to do a thread event poll
  
      private final static int CALL_POLL_COUNT = 0xFFF;
  
      // runtime, nil, and runtimeCache cached here for speed of access from any thread
      public final Ruby runtime;
      public final IRubyObject nil;
      public final RuntimeCache runtimeCache;
      public final boolean is19;
      
      // Is this thread currently with in a function trace?
      private boolean isWithinTrace;
      
      private RubyThread thread;
      private RubyThread rootThread// thread for fiber purposes
      private WeakReference<ThreadFiberfiber = new WeakReference<ThreadFiber>(null);
      private ThreadFiber rootFiber// hard anchor for root threads' fibers
      // Cache format string because it is expensive to create on demand
     private RubyDateFormatter dateFormatter;
     
     private RubyModule[] parentStack = new RubyModule[];
     private int parentIndex = -1;
     
     private Frame[] frameStack = new Frame[];
     private int frameIndex = -1;
 
     private int backtraceIndex = -1;
     
     // List of active dynamic scopes.  Each of these may have captured other dynamic scopes
     // to implement closures.
     private DynamicScope[] scopeStack = new DynamicScope[];
     private int scopeIndex = -1;
 
     private static final Continuation[] EMPTY_CATCHTARGET_STACK = new Continuation[0];
     private int catchIndex = -1;
     
     private boolean isProfiling = false;
     // The flat profile data for this thread
 	
     private boolean eventHooksEnabled = true;
 
 
 
     IRubyObject lastExitStatus;
    
    
Constructor for Context.
 
     private ThreadContext(Ruby runtime) {
         this. = runtime;
         this. = runtime.getNil();
         this. = runtime.is1_9();
         if (runtime.getInstanceConfig().isProfilingEntireRun())
             startProfiling();
 
         this. = runtime.getRuntimeCache();
         
         // TOPLEVEL self and a few others want a top-level scope.  We create this one right
         // away and then pass it into top-level parse so it ends up being the top level.
         StaticScope topStaticScope = runtime.getStaticScopeFactory().newLocalScope(null);
         pushScope(new ManyVarsDynamicScope(topStaticScopenull));
 
         Frame[] stack = ;
         int length = stack.length;
         for (int i = 0; i < lengthi++) {
             stack[i] = new Frame();
         }
         BacktraceElement[] stack2 = ;
         int length2 = stack2.length;
         for (int i = 0; i < length2i++) {
             stack2[i] = new BacktraceElement();
         }
         ThreadContext.pushBacktrace(this"""", 0);
         ThreadContext.pushBacktrace(this"""", 0);
     }
 
     @Override
     protected void finalize() throws Throwable {
         if ( != null) {
             .dispose();
         }
     }

    
Retrieve the runtime associated with this context. Note that there's no reason to call this method rather than accessing the runtime field directly.

Returns:
the runtime associated with this context
See also:
runtime
 
     public final Ruby getRuntime() {
         return ;
     }
     
     public IRubyObject getErrorInfo() {
         return .getErrorInfo();
     }
     
     public IRubyObject setErrorInfo(IRubyObject errorInfo) {
         .setErrorInfo(errorInfo);
         return errorInfo;
     }
     
     public ReturnJump returnJump(IRubyObject value) {
         return new ReturnJump(getFrameJumpTarget(), value);
     }
    
    
Returns the lastCallStatus.

Returns:
LastCallStatus
 
     public void setLastCallStatus(CallType callType) {
          = callType;
     }
 
     public CallType getLastCallType() {
         return ;
     }
 
     public void setLastVisibility(Visibility visibility) {
          = visibility;
     }
 
     public Visibility getLastVisibility() {
         return ;
     }
     
     public void setLastCallStatusAndVisibility(CallType callTypeVisibility visibility) {
          = callType;
          = visibility;
     }
     
     public IRubyObject getLastExitStatus() {
         return ;
     }
     
     public void setLastExitStatus(IRubyObject lastExitStatus) {
         this. = lastExitStatus;
     }
 
     public void printScope() {
         .debug("SCOPE STACK:");
         for (int i = 0; i <= i++) {
             .debug("{}"[i]);
         }
     }
 
     public DynamicScope getCurrentScope() {
         return [];
     }
 
     public StaticScope getCurrentStaticScope() {
         return [].getStaticScope();
     }
     
     public DynamicScope getPreviousScope() {
         return [ - 1];
     }
     
     private void expandFramesIfNecessary() {
         int newSize = . * 2;
          = fillNewFrameStack(new Frame[newSize], newSize);
     }
 
     private Frame[] fillNewFrameStack(Frame[] newFrameStackint newSize) {
         System.arraycopy(, 0, newFrameStack, 0, .);
 
         for (int i = .i < newSizei++) {
             newFrameStack[i] = new Frame();
         }
         
         return newFrameStack;
     }
     
     private void expandParentsIfNecessary() {
         int newSize = . * 2;
         RubyModule[] newParentStack = new RubyModule[newSize];
 
         System.arraycopy(, 0, newParentStack, 0, .);
 
          = newParentStack;
     }
     
     public void pushScope(DynamicScope scope) {
         int index = ++;
         DynamicScope[] stack = ;
         stack[index] = scope;
         if (index + 1 == stack.length) {
             expandScopesIfNecessary();
         }
     }
     
     public void popScope() {
         [--] = null;
     }
     
     private void expandScopesIfNecessary() {
         int newSize = . * 2;
         DynamicScope[] newScopeStack = new DynamicScope[newSize];
 
         System.arraycopy(, 0, newScopeStack, 0, .);
 
          = newScopeStack;
     }
     
     public RubyThread getThread() {
         return ;
     }
     
     public RubyThread getFiberCurrentThread() {
         if ( != nullreturn ;
         return ;
     }
     
         if ( == null)
              = new RubyDateFormatter(this);
         return ;
     }
     
     public void setThread(RubyThread thread) {
         this. = thread;
         this. = thread// may be reset by fiber
 
         // associate the thread with this context, unless we're clearing the reference
         if (thread != null) {
             thread.setContext(this);
         }
     }
     
     public ThreadFiber getFiber() {
         ThreadFiber f = .get();
         
         if (f == nullreturn ;
         
         return f;
     }
     
     public void setFiber(ThreadFiber fiber) {
         this. = new WeakReference(fiber);
     }
     
     public void setRootFiber(ThreadFiber rootFiber) {
         this. = rootFiber;
     }
     
     public void setRootThread(RubyThread rootThread) {
         this. = rootThread;
     }
     
     //////////////////// CATCH MANAGEMENT ////////////////////////
     private void expandCatchIfNecessary() {
         int newSize = . * 2;
         if (newSize == 0) newSize = 1;
         Continuation[] newCatchStack = new Continuation[newSize];
 
         System.arraycopy(, 0, newCatchStack, 0, .);
          = newCatchStack;
     }
     
     public void pushCatch(Continuation catchTarget) {
         int index = ++;
         if (index == .) {
             expandCatchIfNecessary();
         }
         [index] = catchTarget;
     }
     
     public void popCatch() {
         --;
     }

    
Find the active Continuation for the given tag. Must be called with an interned string.

Parameters:
tag The interned string to search for
Returns:
The continuation associated with this tag
 
     public Continuation getActiveCatch(Object tag) {
         for (int i = i >= 0; i--) {
             Continuation c = [i];
             if (.is1_9()) {
                 if (c.tag == tagreturn c;
             } else {
                 if (c.tag.equals(tag)) return c;
             }
         }
         return null;
     }
     
     //////////////////// FRAME MANAGEMENT ////////////////////////
     private void pushFrameCopy() {
         int index = ++this.;
         Frame[] stack = ;
         Frame currentFrame = stack[index - 1];
         stack[index].updateFrame(currentFrame);
         if (index + 1 == stack.length) {
             expandFramesIfNecessary();
         }
     }
     
     private Frame pushFrame(Frame frame) {
         int index = ++this.;
         Frame[] stack = ;
         stack[index] = frame;
         if (index + 1 == stack.length) {
             expandFramesIfNecessary();
         }
         return frame;
     }
     
     private void pushCallFrame(RubyModule clazzString name
                                IRubyObject selfBlock block) {
         int index = ++this.;
         Frame[] stack = ;
         stack[index].updateFrame(clazzselfnameblock);
         if (index + 1 == stack.length) {
             expandFramesIfNecessary();
         }
     }
     
     private void pushEvalFrame(IRubyObject self) {
         int index = ++this.;
         Frame[] stack = ;
         stack[index].updateFrameForEval(self);
         if (index + 1 == stack.length) {
             expandFramesIfNecessary();
         }
     }
     
     public void pushFrame() {
         int index = ++this.;
         Frame[] stack = ;
         if (index + 1 == stack.length) {
             expandFramesIfNecessary();
         }
     }
     
     public void popFrame() {
         Frame[] stack = ;
         int index = --;
         Frame frame = stack[index];
         
         // if the frame was captured, we must replace it but not clear
         if (frame.isCaptured()) {
             stack[index] = new Frame();
         } else {
             frame.clear();
         }
     }
         
     private void popFrameReal(Frame oldFrame) {
         [--] = oldFrame;
     }
     
     public Frame getCurrentFrame() {
         return [];
     }
     
     public Frame getNextFrame() {
         int index = ;
         Frame[] stack = ;
         if (index + 1 == stack.length) {
             expandFramesIfNecessary();
         }
         return stack[index + 1];
     }
     
     public Frame getPreviousFrame() {
         int index = ;
         return index < 1 ? null : [index - 1];
     }
    
    
Set the $~ (backref) "global" to the given value.

Parameters:
match the value to set
Returns:
the value passed in
 
     public IRubyObject setBackRef(IRubyObject match) {
         return getCurrentFrame().setBackRef(match);
     }
    
    
Get the value of the $~ (backref) "global".

Returns:
the value of $~
 
     public IRubyObject getBackRef() {
         return getCurrentFrame().getBackRef();
     }
    
    
Set the $_ (lastlne) "global" to the given value.

Parameters:
last the value to set
Returns:
the value passed in
 
     public IRubyObject setLastLine(IRubyObject last) {
         return getCurrentFrame().setLastLine(last);
     }
    
    
Get the value of the $_ (lastline) "global".

Returns:
the value of $_
 
     public IRubyObject getLastLine() {
         return getCurrentFrame().getLastLine();
     }
 
     /////////////////// BACKTRACE ////////////////////
 
     private static void expandBacktraceIfNecessary(ThreadContext context) {
         int newSize = context.backtrace.length * 2;
         context.backtrace = fillNewBacktrace(contextnew BacktraceElement[newSize], newSize);
     }
 
     private static BacktraceElement[] fillNewBacktrace(ThreadContext contextBacktraceElement[] newBacktraceint newSize) {
         System.arraycopy(context.backtrace, 0, newBacktrace, 0, context.backtrace.length);
 
         for (int i = context.backtrace.lengthi < newSizei++) {
             newBacktrace[i] = new BacktraceElement();
         }
 
         return newBacktrace;
     }
 
     public static void pushBacktrace(ThreadContext contextString methodISourcePosition position) {
         int index = ++context.backtraceIndex;
         BacktraceElement[] stack = context.backtrace;
         BacktraceElement.update(stack[index], methodposition);
         if (index + 1 == stack.length) {
             ThreadContext.expandBacktraceIfNecessary(context);
         }
     }
 
     public static void pushBacktrace(ThreadContext contextString methodString fileint line) {
         int index = ++context.backtraceIndex;
         BacktraceElement[] stack = context.backtrace;
         BacktraceElement.update(stack[index], methodfileline);
         if (index + 1 == stack.length) {
             ThreadContext.expandBacktraceIfNecessary(context);
         }
     }
 
     public static void popBacktrace(ThreadContext context) {
         context.backtraceIndex--;
     }

    
Search the frame stack for the given JumpTarget. Return true if it is found and false otherwise. Skip the given number of frames before beginning the search.

Parameters:
target The JumpTarget to search for
skipFrames The number of frames to skip before searching
Returns:
 
     public boolean isJumpTargetAlive(int targetint skipFrames) {
         for (int i =  - skipFramesi >= 0; i--) {
             if ([i].getJumpTarget() == targetreturn true;
         }
         return false;
     }

    
Check if a static scope is present on the call stack. This is the IR equivalent of isJumpTargetAlive

Parameters:
s the static scope to look for
Returns:
true if it exists false if not
 
     public boolean scopeExistsOnCallStack(StaticScope s) {
         DynamicScope[] stack = ;
         for (int i = i >= 0; i--) {
            if (stack[i].getStaticScope() == sreturn true;
         }
         return false;
     }
     
     public String getFrameName() {
         return getCurrentFrame().getName();
     }
     
     public IRubyObject getFrameSelf() {
         return getCurrentFrame().getSelf();
     }
     
     public int getFrameJumpTarget() {
         return getCurrentFrame().getJumpTarget();
     }
     
     public RubyModule getFrameKlazz() {
         return getCurrentFrame().getKlazz();
     }
     
     public Block getFrameBlock() {
         return getCurrentFrame().getBlock();
     }
     
     public String getFile() {
         return [].;
     }
     
     public int getLine() {
         return [].;
     }
     
     public void setLine(int line) {
         []. = line;
     }
     
     public void setFileAndLine(String fileint line) {
         BacktraceElement b = [];
         b.filename = file;
         b.line = line;
     }
 
     public void setFileAndLine(ISourcePosition position) {
         BacktraceElement b = [];
         b.filename = position.getFile();
         b.line = position.getStartLine();
     }
     
     public Visibility getCurrentVisibility() {
         return getCurrentFrame().getVisibility();
     }
     
     public Visibility getPreviousVisibility() {
         return getPreviousFrame().getVisibility();
     }
     
     public void setCurrentVisibility(Visibility visibility) {
         getCurrentFrame().setVisibility(visibility);
     }
     
     public void pollThreadEvents() {
         .pollThreadEvents(this);
     }
     
     public int callNumber = 0;
 
     public int getCurrentTarget() {
         return ;
     }
     
     public void callThreadPoll() {
         if ((++ & ) == 0) pollThreadEvents();
     }
 
     public static void callThreadPoll(ThreadContext context) {
         if ((context.callNumber++ & ) == 0) context.pollThreadEvents();
     }
     
     public void trace(RubyEvent eventString nameRubyModule implClass) {
         trace(eventnameimplClass[].[].);
     }
 
     public void trace(RubyEvent eventString nameRubyModule implClassString fileint line) {
         .callEventHooks(thiseventfilelinenameimplClass);
     }
     
     public void pushRubyClass(RubyModule currentModule) {
         // FIXME: this seems like a good assertion, but it breaks compiled code and the code seems
         // to run without it...
         //assert currentModule != null : "Can't push null RubyClass";
         int index = ++;
         RubyModule[] stack = ;
         stack[index] = currentModule;
         if (index + 1 == stack.length) {
             expandParentsIfNecessary();
         }
     }
     
     public RubyModule popRubyClass() {
         int index = ;
         RubyModule[] stack = ;
         RubyModule ret = stack[index];
         stack[index] = null;
          = index - 1;
         return ret;
     }
     
     public RubyModule getRubyClass() {
         assert  != -1 : "Trying to get RubyClass from empty stack";
         RubyModule parentModule = [];
         return parentModule.getNonIncludedClass();
     }
 
     public RubyModule getPreviousRubyClass() {
         assert  != 0 : "Trying to get RubyClass from too-shallow stack";
         RubyModule parentModule = [ - 1];
         return parentModule.getNonIncludedClass();
     }
 
     @Deprecated
     public boolean getConstantDefined(String internedName) {
         return getCurrentStaticScope().isConstantDefined(internedName);
     }
    
    
Used by the evaluator and the compiler to look up a constant by name
 
     @Deprecated
     public IRubyObject getConstant(String internedName) {
         return getCurrentStaticScope().getConstant(internedName);
     }

    
Used by the evaluator and the compiler to set a constant by name This is for a null const decl
 
     @Deprecated
     public IRubyObject setConstantInCurrent(String internedNameIRubyObject result) {
         return getCurrentStaticScope().setConstant(internedNameresult);
     }
    
    
Used by the evaluator and the compiler to set a constant by name. This is for a Colon2 const decl
 
     @Deprecated
     public IRubyObject setConstantInModule(String internedNameIRubyObject targetIRubyObject result) {
         if (!(target instanceof RubyModule)) {
             throw .newTypeError(target.toString() + " is not a class/module");
         }
         RubyModule module = (RubyModule)target;
         module.setConstant(internedNameresult);
         
         return result;
     }
    
    
Used by the evaluator and the compiler to set a constant by name This is for a Colon2 const decl
 
     @Deprecated
     public IRubyObject setConstantInObject(String internedNameIRubyObject result) {
         .getObject().setConstant(internedNameresult);
         
         return result;
     }
     
     private static void addBackTraceElement(Ruby runtimeRubyArray backtraceRubyStackTraceElement element) {
         RubyString str = RubyString.newString(runtimeelement.mriStyleString());
         backtrace.append(str);
     }
    
    
Create an Array with backtrace information for Kernel#caller

Parameters:
runtime
level
Returns:
an Array with the backtrace
 
     public IRubyObject createCallerBacktrace(int levelStackTraceElement[] stacktrace) {
         return createCallerBacktrace(levelnullstacktrace);
     }

    
Create an Array with backtrace information for Kernel#caller

Parameters:
runtime
level
length
Returns:
an Array with the backtrace
 
     public IRubyObject createCallerBacktrace(int levelInteger lengthStackTraceElement[] stacktrace) {
         .incrementCallerCount();
         
         RubyStackTraceElement[] trace = getTraceSubset(levellengthstacktrace);
         
         if (trace == nullreturn ;
         
         RubyArray newTrace = .newArray(trace.length);
 
         for (int i = leveli - level < trace.lengthi++) {
             addBackTraceElement(newTracetrace[i - level]);
         }
         
         if (.) TraceType.dumpCaller(newTrace);
         
         return newTrace;
     }

    
Create an array containing Thread::Backtrace::Location objects for the requested caller trace level and length.

Parameters:
level the level at which the trace should start
length the length of the trace
Returns:
an Array with the backtrace locations
 
     public IRubyObject createCallerLocations(int levelInteger lengthStackTraceElement[] stacktrace) {
         RubyStackTraceElement[] trace = getTraceSubset(levellengthstacktrace);
         
         if (trace == nullreturn ;
         
         return RubyThread.Location.newLocationArray(trace);
     }
     
     private RubyStackTraceElement[] getTraceSubset(int levelInteger lengthStackTraceElement[] stacktrace) {
         .incrementCallerCount();
         
         if (length != null && length == 0) return new RubyStackTraceElement[0];
         
         RubyStackTraceElement[] trace =
                 ...getBacktraceData(thisstacktracefalse).getBacktrace();
         
         int traceLength = safeLength(levellengthtrace);
         
         if (traceLength < 0) return null;
         
         trace = Arrays.copyOfRange(tracelevellevel + traceLength);
         
         if (.) TraceType.dumpCaller(trace);
         
         return trace;
     }
     
     private static int safeLength(int levelInteger lengthRubyStackTraceElement[] trace) {
         int baseLength = trace.length - level;
         return length != null ? Math.min(lengthbaseLength) : baseLength;
     }

    
Create an Array with backtrace information for a built-in warning

Parameters:
runtime
Returns:
an Array with the backtrace
 
     public RubyStackTraceElement[] createWarningBacktrace(Ruby runtime) {
         runtime.incrementWarningCount();
 
         RubyStackTraceElement[] trace = gatherCallerBacktrace();
 
         if (.) TraceType.dumpWarning(trace);
 
         return trace;
     }
     
         Thread nativeThread = .getNativeThread();
 
         // Future thread or otherwise unforthgiving thread impl.
         if (nativeThread == nullreturn new RubyStackTraceElement[] {};
 
         BacktraceElement[] copy = new BacktraceElement[ + 1];
 
         System.arraycopy(, 0, copy, 0,  + 1);
         RubyStackTraceElement[] trace = ..getBacktraceData(thisfalse).getBacktrace();
 
         return trace;
     }
    
    
Create an Array with backtrace information.

Parameters:
level
nativeException
Returns:
an Array with the backtrace
 
     public Frame[] createBacktrace(int levelboolean nativeException) {
         int traceSize =  - level + 1;
         Frame[] traceFrames;
         
         if (traceSize <= 0) return null;
         
         if (nativeException) {
             // assert level == 0;
             traceFrames = new Frame[traceSize + 1];
             traceFrames[traceSize] = [];
         } else {
             traceFrames = new Frame[traceSize];
         }
         
         System.arraycopy(, 0, traceFrames, 0, traceSize);
         
         return traceFrames;
     }
 
     public boolean isEventHooksEnabled() {
         return ;
     }
 
     public void setEventHooksEnabled(boolean flag) {
          = flag;
     }
    
    
Create an Array with backtrace information.

Parameters:
level
nativeException
Returns:
an Array with the backtrace
 
     public BacktraceElement[] createBacktrace2(int levelboolean nativeException) {
         BacktraceElement[] backtraceClone = .clone();
         int backtraceIndex = this.;
         BacktraceElement[] newTrace = new BacktraceElement[backtraceIndex + 1];
         for (int i = 0; i <= backtraceIndexi++) {
             newTrace[i] = backtraceClone[i];
         }
         return newTrace;
     }
     
     private static String createRubyBacktraceString(StackTraceElement element) {
         return element.getFileName() + ":" + element.getLineNumber() + ":in `" + element.getMethodName() + "'";
     }
     
         StackTraceElement[] javaStackTrace = t.getStackTrace();
         
         StringBuilder buffer = new StringBuilder();
         if (javaStackTrace != null && javaStackTrace.length > 0) {
             StackTraceElement element = javaStackTrace[0];
 
             buffer
                     .append(createRubyBacktraceString(element))
                     .append(": ")
                     .append(t.toString())
                     .append("\n");
             for (int i = 1; i < javaStackTrace.lengthi++) {
                 element = javaStackTrace[i];
                 
                 buffer
                         .append("\tfrom ")
                         .append(createRubyBacktraceString(element));
                 if (i + 1 < javaStackTrace.lengthbuffer.append("\n");
             }
         }
         
         return buffer.toString();
     }
 
     public static RubyStackTraceElement[] gatherRawBacktrace(Ruby runtimeStackTraceElement[] stackTrace) {
         List trace = new ArrayList(stackTrace.length);
         
         for (int i = 0; i < stackTrace.lengthi++) {
             StackTraceElement element = stackTrace[i];
             trace.add(new RubyStackTraceElement(element));
         }
 
         RubyStackTraceElement[] rubyStackTrace = new RubyStackTraceElement[trace.size()];
         return (RubyStackTraceElement[])trace.toArray(rubyStackTrace);
     }
 
     private Frame pushFrameForBlock(Binding binding) {
         Frame lastFrame = getNextFrame();
         Frame f = pushFrame(binding.getFrame());
         f.setVisibility(binding.getVisibility());
         
         return lastFrame;
     }
 
     private Frame pushFrameForEval(Binding binding) {
         Frame lastFrame = getNextFrame();
         Frame f = pushFrame(binding.getFrame());
         f.setVisibility(binding.getVisibility());
         return lastFrame;
     }
     
     public void preAdoptThread() {
         pushFrame();
         pushRubyClass(.getObject());
     }
 
     public void preExtensionLoad(IRubyObject self) {
         pushFrame();
         pushRubyClass(.getObject());
         getCurrentFrame().setSelf(self);
     }
 
     public void postExtensionLoad() {
         popFrame();
         popRubyClass();
     }
     
     public void preCompiledClass(RubyModule typeStaticScope staticScope) {
         pushRubyClass(type);
         pushFrameCopy();
         getCurrentFrame().setSelf(type);
         staticScope.setModule(type);
         pushScope(DynamicScope.newDynamicScope(staticScope));
     }
 
     public void preCompiledClassDummyScope(RubyModule typeStaticScope staticScope) {
         pushRubyClass(type);
         pushFrameCopy();
         getCurrentFrame().setSelf(type);
         staticScope.setModule(type);
         pushScope(staticScope.getDummyScope());
     }
 
     public void postCompiledClass() {
         popScope();
         popRubyClass();
         popFrame();
     }
     
     public void preScopeNode(StaticScope staticScope) {
         pushScope(DynamicScope.newDynamicScope(staticScopegetCurrentScope()));
     }
 
     public void postScopeNode() {
         popScope();
     }
 
    public void preClassEval(StaticScope staticScopeRubyModule type) {
        pushRubyClass(type);
        pushFrameCopy();
        getCurrentFrame().setSelf(type);
        pushScope(DynamicScope.newDynamicScope(staticScopenull));
    }
    
    public void postClassEval() {
        popScope();
        popRubyClass();
        popFrame();
    }
    
    public void preBsfApply(String[] names) {
        // FIXME: I think we need these pushed somewhere?
        StaticScope staticScope = .getStaticScopeFactory().newLocalScope(null);
        staticScope.setVariables(names);
        pushFrame();
    }
    
    public void postBsfApply() {
        popFrame();
    }
    public void preMethodFrameAndClass(RubyModule implClassString nameIRubyObject selfBlock blockStaticScope staticScope) {
        RubyModule ssModule = staticScope.getModule();
        // FIXME: This is currently only here because of some problems with IOOutputStream writing to a "bare" runtime without a proper scope
        if (ssModule == nullssModule = implClass;
        pushRubyClass(ssModule);
        pushCallFrame(implClassnameselfblock);
    }
    
    public void preMethodFrameAndScope(RubyModule clazzString nameIRubyObject selfBlock block
            StaticScope staticScope) {
        RubyModule implementationClass = staticScope.getModule();
        // FIXME: This is currently only here because of some problems with IOOutputStream writing to a "bare" runtime without a proper scope
        if (implementationClass == null) {
            implementationClass = clazz;
        }
        pushCallFrame(clazznameselfblock);
        pushScope(DynamicScope.newDynamicScope(staticScope));
        pushRubyClass(implementationClass);
    }
    
    public void preMethodFrameAndDummyScope(RubyModule clazzString nameIRubyObject selfBlock block
            StaticScope staticScope) {
        RubyModule implementationClass = staticScope.getModule();
        // FIXME: This is currently only here because of some problems with IOOutputStream writing to a "bare" runtime without a proper scope
        if (implementationClass == null) {
            implementationClass = clazz;
        }
        pushCallFrame(clazznameselfblock);
        pushScope(staticScope.getDummyScope());
        pushRubyClass(implementationClass);
    }
    public void preMethodNoFrameAndDummyScope(RubyModule clazzStaticScope staticScope) {
        RubyModule implementationClass = staticScope.getModule();
        // FIXME: This is currently only here because of some problems with IOOutputStream writing to a "bare" runtime without a proper scope
        if (implementationClass == null) {
            implementationClass = clazz;
        }
        pushScope(staticScope.getDummyScope());
        pushRubyClass(implementationClass);
    }
    
    public void postMethodFrameAndScope() {
        popRubyClass();
        popScope();
        popFrame();
    }
    
    public void preMethodFrameOnly(RubyModule clazzString nameIRubyObject selfBlock block) {
        pushRubyClass(clazz);
        pushCallFrame(clazznameselfblock);
    }
    
    public void postMethodFrameOnly() {
        popFrame();
        popRubyClass();
    }
    
    public void preMethodScopeOnly(RubyModule clazzStaticScope staticScope) {
        RubyModule implementationClass = staticScope.getModule();
        // FIXME: This is currently only here because of some problems with IOOutputStream writing to a "bare" runtime without a proper scope
        if (implementationClass == null) {
            implementationClass = clazz;
        }
        pushScope(DynamicScope.newDynamicScope(staticScope));
        pushRubyClass(implementationClass);
    }
    
    public void postMethodScopeOnly() {
        popRubyClass();
        popScope();
    }
    
    public void preMethodBacktraceAndScope(String nameRubyModule clazzStaticScope staticScope) {
        preMethodScopeOnly(clazzstaticScope);
    }
    
    public void postMethodBacktraceAndScope() {
        postMethodScopeOnly();
    }
    
    public void preMethodBacktraceOnly(String name) {
    }
    public void preMethodBacktraceDummyScope(RubyModule clazzString nameStaticScope staticScope) {
        RubyModule implementationClass = staticScope.getModule();
        // FIXME: This is currently only here because of some problems with IOOutputStream writing to a "bare" runtime without a proper scope
        if (implementationClass == null) {
            implementationClass = clazz;
        }
        pushScope(staticScope.getDummyScope());
        pushRubyClass(implementationClass);
    }
    
    public void postMethodBacktraceOnly() {