Index: org/jruby/evaluator/EvaluationState.java
===================================================================
--- org/jruby/evaluator/EvaluationState.java	(revision 2114)
+++ org/jruby/evaluator/EvaluationState.java	(working copy)
@@ -30,15 +30,17 @@
 import org.jruby.util.UnsynchronizedStack;
 
 public class EvaluationState {
-	//private IRubyObject result;
-    private UnsynchronizedStack results = new UnsynchronizedStack();
+	private IRubyObject result;
+    private UnsynchronizedStack results = null;
+    
 	public final IRuby runtime;
 	private IRubyObject self;
 	public final EvaluateVisitor evaluator;
-    private UnsynchronizedStack instructionBundleStacks = new UnsynchronizedStack();
+    
+    private UnsynchronizedStack instructionBundleStacks = null;
+    private InstructionBundle currentStack;
+    
     private JumpException currentException;
-    private boolean handlingException;
-    private InstructionBundle currentStack;
     
     public EvaluationState(IRuby runtime, IRubyObject self) {
         this.runtime = runtime;
@@ -44,8 +46,8 @@
         this.runtime = runtime;
         this.evaluator = EvaluateVisitor.getInstance();
         
-        results.push(runtime.getNil());
-        
+        result = runtime.getNil();
+         
         setSelf(self);
     }
     
@@ -51,6 +53,10 @@
     
     // FIXME: exceptions thrown during aggregation cause this to leak
     public void aggregateResult() {
+        if (results == null) {
+            results = new UnsynchronizedStack();
+            results.push(result);
+        }
         results.push(runtime.getNil());
     }
     
@@ -58,6 +64,37 @@
         return (IRubyObject)results.pop();
     }
     
+    /**
+     * @param result The result to set.
+     */
+    public void setResult(IRubyObject result) {
+        if (results == null) {
+            this.result = result;
+        } else {
+            results.set(results.size() - 1, result);
+        }
+    }
+    
+    /**
+     * @return Returns the result.
+     */
+    public IRubyObject getResult() {
+        if (results == null) {
+            return result;
+        } else {
+            return (IRubyObject)results.peek();
+        }
+    }
+    
+    public void clearResult() {
+        setResult(runtime.getNil());
+    }
+    
+    public void flushResults() {
+        results = null;
+        result = runtime.getNil();
+    }
+    
     public Instruction peekCurrentInstruction() {
         return getCurrentInstructionStack().instruction;
     }
@@ -103,6 +140,7 @@
 	 * Push down a new pair of node and visitor stacks
 	 */
 	public void pushCurrentInstructionStack() {
+        if (instructionBundleStacks == null) instructionBundleStacks = new UnsynchronizedStack();
 	    if (currentStack == null && instructionBundleStacks.isEmpty()) {
             return;
         }
@@ -188,29 +226,6 @@
         
         addInstructionBundle(ib);
     }
-	
-	/**
-	 * @param result The result to set.
-	 */
-	public void setResult(IRubyObject result) {
-		results.set(results.size() - 1, result);
-	}
-    
-	/**
-	 * @return Returns the result.
-	 */
-	public IRubyObject getResult() {
-		return (IRubyObject)results.peek();
-	}
-    
-	public void clearResult() {
-		setResult(runtime.getNil());
-	}
-	
-	public void flushResults() {
-		results.clear();
-        results.push(runtime.getNil());
-	}
     
 	/**
 	 * @param self The self to set.
@@ -254,13 +269,14 @@
     public void executeNext() {
         try {
             // FIXME: Poll from somewhere else in the code? This polls per-node, perhaps per newline?
-            getThreadContext().pollThreadEvents();
+            //getThreadContext().pollThreadEvents();
             
             InstructionBundle ib = popCurrentInstruction();
             
-            if (ib != null) {
+            //if (ib != null) {
                 ib.instruction.execute(this, ib.instructionContext);
-            }
+            //}
+        } catch (NullPointerException npe) {
         } catch (JumpException je) {
             if (je.getJumpType() == JumpException.JumpType.RedoJump) {
                 handleRedo(je);
@@ -288,6 +304,10 @@
             return getResult();
         }
         
+        // FIXME: This is a minor hack that depends on us being called in recursion; safe for now
+        InstructionBundle previousStack = currentStack;
+        currentStack = null;
+        
         begin2(node);
         
         try {
@@ -300,6 +320,7 @@
                 // TODO: perhaps a better place to catch this (although it will go away)
                 throw runtime.newSystemStackError("stack level too deep");
         } finally {
+            currentStack = previousStack;
             end();
         }
         
@@ -311,7 +332,8 @@
         
         if (node != null) {
             // for each call to internalEval, push down new stacks (to isolate eval runs that still want to be logically separate
-            pushCurrentInstructionStack();
+            // FIXME: If we ever go pure iterative, this will need to be added back or re-thought
+            //if (currentStack != null) pushCurrentInstructionStack();
             
             addNodeInstruction(node);
         }
@@ -318,7 +340,8 @@
     }
     
     public void end() {
-        popCurrentInstructionStack();
+        // FIXME: If we ever go pure iterative, this will need to be added back or re-thought
+        //if (instructionBundleStacks != null) popCurrentInstructionStack();
     }
     
     private void handleNext(JumpException je) {
Index: org/jruby/evaluator/..rej
===================================================================
--- org/jruby/evaluator/..rej	
+++ org/jruby/evaluator/..rej	
@@ -0,0 +1,9 @@
+@@ -43,7 +43,7 @@
+         this.runtime = runtime;
+         this.evaluator = EvaluateVisitor.getInstance();
+         
+-        results.push(runtime.getNil());
++        result = runtime.getNil();
+         
+         setSelf(self);
+     }
