Index: src/org/jruby/evaluator/EvaluateVisitor.java
===================================================================
RCS file: /cvsroot/jruby/jruby/src/org/jruby/evaluator/EvaluateVisitor.java,v
retrieving revision 1.125
diff -u -r1.125 EvaluateVisitor.java
--- src/org/jruby/evaluator/EvaluateVisitor.java	9 Mar 2006 18:09:21 -0000	1.125
+++ src/org/jruby/evaluator/EvaluateVisitor.java	15 Mar 2006 02:59:59 -0000
@@ -522,14 +522,14 @@
     private static class CallNodeVisitor implements Instruction {
     	public void execute(EvaluationState state, InstructionContext ctx) {
     		CallNode iVisited = (CallNode)ctx;
-            Block tmpBlock = state.getThreadContext().beginCallArgs();
+            state.getThreadContext().beginCallArgs();
             IRubyObject receiver = null;
             IRubyObject[] args = null;
             try {
                 receiver = state.begin(iVisited.getReceiverNode());
                 args = setupArgs(state, state.runtime, state.getThreadContext(), iVisited.getArgsNode());
             } finally {
-            	state.getThreadContext().endCallArgs(tmpBlock);
+            	state.getThreadContext().endCallArgs();
             }
             assert receiver.getMetaClass() != null : receiver.getClass().getName();
             if (iVisited.getName().equals("blah")) ;
@@ -1017,12 +1017,12 @@
     private static class FCallNodeVisitor implements Instruction {
     	public void execute(EvaluationState state, InstructionContext ctx) {
     		FCallNode iVisited = (FCallNode)ctx;
-            Block tmpBlock = state.getThreadContext().beginCallArgs();
-            IRubyObject[] args;
+            state.getThreadContext().beginCallArgs();
+            IRubyObject[] args = null;
             try {
                 args = setupArgs(state, state.runtime, state.getThreadContext(), iVisited.getArgsNode());
             } finally {
-            	state.getThreadContext().endCallArgs(tmpBlock);
+            	state.getThreadContext().endCallArgs();
             }
 
             state.setResult(state.getSelf().callMethod(iVisited.getName(), args, CallType.FUNCTIONAL));
@@ -1083,14 +1083,14 @@
                 while (true) {
                     try {
                         ISourcePosition position = state.getThreadContext().getPosition();
-                        Block tmpBlock = state.getThreadContext().beginCallArgs();
+                        state.getThreadContext().beginCallArgs();
 
                         IRubyObject recv = null;
                         try {
                             recv = state.begin(iVisited.getIterNode());
                         } finally {
                             state.getThreadContext().setPosition(position);
-                            state.getThreadContext().endCallArgs(tmpBlock);
+                            state.getThreadContext().endCallArgs();
                         }
                         
                         state.setResult(recv.callMethod("each", IRubyObject.NULL_ARRAY, CallType.NORMAL));
@@ -1825,13 +1825,13 @@
                 throw state.runtime.newNameError("Superclass method '" + state.getThreadContext().getCurrentFrame().getLastFunc() + "' disabled.");
             }
 
-            Block tmpBlock = state.getThreadContext().beginCallArgs();
+            state.getThreadContext().beginCallArgs();
 
             IRubyObject[] args = null;
             try {
                 args = setupArgs(state, state.runtime, state.getThreadContext(), iVisited.getArgsNode());
             } finally {
-            	state.getThreadContext().endCallArgs(tmpBlock);
+            	state.getThreadContext().endCallArgs();
             }
             state.setResult(state.getThreadContext().callSuper(args));
     	}
Index: src/org/jruby/evaluator/EvaluationState.java
===================================================================
RCS file: /cvsroot/jruby/jruby/src/org/jruby/evaluator/EvaluationState.java,v
retrieving revision 1.11
diff -u -r1.11 EvaluationState.java
--- src/org/jruby/evaluator/EvaluationState.java	14 Mar 2006 03:23:05 -0000	1.11
+++ src/org/jruby/evaluator/EvaluationState.java	15 Mar 2006 03:00:00 -0000
@@ -540,13 +540,13 @@
             return currentException.isKindOf(runtime.getClass("StandardError"));
         }
 
-        Block tmpBlock = getThreadContext().beginCallArgs();
+        getThreadContext().beginCallArgs();
 
         IRubyObject[] args = null;
         try {
             args = setupArgs(runtime, getThreadContext(), exceptionNodes);
         } finally {
-            getThreadContext().endCallArgs(tmpBlock);
+            getThreadContext().endCallArgs();
         }
 
         for (int i = 0; i < args.length; i++) {
Index: src/org/jruby/runtime/Block.java
===================================================================
RCS file: /cvsroot/jruby/jruby/src/org/jruby/runtime/Block.java,v
retrieving revision 1.27
diff -u -r1.27 Block.java
--- src/org/jruby/runtime/Block.java	10 Feb 2006 21:53:26 -0000	1.27
+++ src/org/jruby/runtime/Block.java	15 Mar 2006 03:00:00 -0000
@@ -104,7 +104,7 @@
     public IRubyObject call(IRubyObject[] args, IRubyObject replacementSelf) {
         IRuby runtime = self.getRuntime();
         ThreadContext context = runtime.getCurrentContext();
-        Block oldBlock = context.getCurrentBlock();
+        //Block oldBlock = context.getCurrentBlock();
         Block newBlock = this.cloneBlock();
         if (replacementSelf != null) {
             newBlock.self = replacementSelf;
@@ -113,7 +113,7 @@
         try {
             return context.yield(runtime.newArray(args), null, null, false, true);
         } finally {
-            context.postBlockYield(oldBlock);
+            context.postBlockYield();
         }
     }
 
Index: src/org/jruby/runtime/ThreadContext.java
===================================================================
RCS file: /cvsroot/jruby/jruby/src/org/jruby/runtime/ThreadContext.java,v
retrieving revision 1.83
diff -u -r1.83 ThreadContext.java
--- src/org/jruby/runtime/ThreadContext.java	9 Mar 2006 20:02:45 -0000	1.83
+++ src/org/jruby/runtime/ThreadContext.java	15 Mar 2006 03:00:00 -0000
@@ -61,7 +61,9 @@
 public class ThreadContext {
     private final IRuby runtime;
 
-    private BlockStack blockStack;
+    //private BlockStack blockStack;
+    //private Block currentBlock;
+    private UnsynchronizedStack blockStack;
     private UnsynchronizedStack dynamicVarsStack;
 
     private RubyThread thread;
@@ -82,7 +84,7 @@
     public ThreadContext(IRuby runtime) {
         this.runtime = runtime;
 
-        this.blockStack = new BlockStack();
+        this.blockStack = new UnsynchronizedStack();
         this.dynamicVarsStack = new UnsynchronizedStack();
         this.frameStack = new UnsynchronizedStack();
         this.iterStack = new UnsynchronizedStack();
@@ -117,19 +119,43 @@
     }
     
     private void pushBlock(Block block) {
-        blockStack.push(block);
+        if (blockStack.isEmpty()) {
+            blockStack.push(block);
+        } else {
+            block.setNext((Block)blockStack.pop());
+            blockStack.push(block);
+        }
     }
     
     private Block popBlock() {
-        return (Block)blockStack.pop();
+        assert blockStack.peek() != null : "Attempt to pop a block when none exists";
+        
+        Block block = (Block)blockStack.pop();
+        Block newBlock = (Block)block.getNext();
+        
+        if (blockStack.isEmpty() && newBlock == null) {
+            // do nothing
+        } else {
+            blockStack.push(block.getNext());
+        }
+        
+        return block;
     }
     
     public Block getCurrentBlock() {
+        if (blockStack.isEmpty()) {
+            return null;
+        }
+
         return (Block)blockStack.peek();
     }
     
     private void setCurrentBlock(Block block) {
-        blockStack.setCurrent(block);
+        blockStack.push(block);
+    }
+    
+    private void unsetCurrentBlock() {
+        blockStack.pop();
     }
 
     public DynamicVariableSet getCurrentDynamicVars() {
@@ -430,7 +456,7 @@
     
     // TODO: This and the following version maybe can be combined after studying usage patterns
     public boolean isBlockGivenAndAvailable() {
-        return getCurrentFrame().isBlockGiven() && blockStack.peek() != null;
+        return getCurrentFrame().isBlockGiven() && getCurrentBlock() != null;
     }
 
     public boolean isBlockGiven() {
@@ -540,19 +566,22 @@
         return result == null ? runtime.getNil() : result;
     }
     
-    public Block beginCallArgs() {
-        Block currentBlock = (Block) blockStack.peek();
+    public void beginCallArgs() {
+        //Block block = getCurrentBlock();
 
-        if (getCurrentIter().isPre()) {
-            blockStack.pop();
+        if (getCurrentIter().isPre() && getCurrentBlock() != null) {
+            setCurrentBlock((Block)getCurrentBlock().getNext());
         }
         iterStack.push(Iter.ITER_NOT);
-        return currentBlock;
+        //return block;
     }
 
-    public void endCallArgs(Block currentBlock) {
-        blockStack.setCurrent(currentBlock);
+    public void endCallArgs(){//Block block) {
+        //setCurrentBlock(block);
         iterStack.pop();
+        if (getCurrentIter().isPre() && !blockStack.isEmpty()) {
+            unsetCurrentBlock();
+        }
     }
     
     public boolean getConstantDefined(String name) {
@@ -848,13 +877,13 @@
         getCurrentFrame().setIter(Iter.ITER_CUR);
     }
     
-    public void postBlockYield(Block oldBlock) {
+    public void postBlockYield() {
         popIter();
-        setCurrentBlock(oldBlock);
+        unsetCurrentBlock();
     }
 
     private Block preYield(RubyModule klass) {
-        Block currentBlock = (Block) blockStack.pop();
+        Block currentBlock = popBlock();
 
         pushFrame(currentBlock.getFrame());
 
@@ -874,7 +903,7 @@
         dynamicVarsStack.pop();
         frameStack.pop();
         
-        blockStack.push(currentBlock);
+        pushBlock(currentBlock);
         popRubyClass();
     }
 
