package org.mozartoz.truffle.nodes.call;

import org.mozartoz.truffle.nodes.OzNode;
import org.mozartoz.truffle.runtime.TailCallException;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.profiles.BranchProfile;

public class TailCallCatcherNode extends OzNode {

	@Child CallNode callNode;

	private final BranchProfile tailCallProfile = BranchProfile.create();

	public TailCallCatcherNode(CallNode callNode) {
		this.callNode = callNode;
	}

	public Object execute(VirtualFrame frame) {
		try {
			return callNode.execute(frame);
		} catch (TailCallException firstException) {
			tailCallProfile.enter();
			TailCallException tailCall = firstException;
			while (true) {
				try {
					return callNode.executeCall(frame, tailCall.receiver, tailCall.arguments);
				} catch (TailCallException exception) {
					tailCall = exception;
				}
			}
		}
	}

}

@@ -587,30 +587,24 @@
 ception 
-firstException
+tailCall
 ) %7B%0A%09%09%09t
@@ -631,56 +631,8 @@
 ();%0A
-%09%09%09TailCallException tailCall = firstException;%0A
 %09%09%09w

Make sure there is no leak in tail calls