package org.mozartoz.truffle.nodes.call;

import org.mozartoz.truffle.nodes.OzNode;
import org.mozartoz.truffle.runtime.OzArguments;
import org.mozartoz.truffle.runtime.OzProc;

import com.oracle.truffle.api.RootCallTarget;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.DirectCallNode;
import com.oracle.truffle.api.nodes.IndirectCallNode;

@NodeChildren({ @NodeChild("proc"), @NodeChild("arguments") })
public abstract class CallProcNode extends OzNode {

	public static CallProcNode create() {
		return CallProcNodeGen.create(null, null);
	}

	public abstract Object executeCall(VirtualFrame frame, OzProc proc, Object[] arguments);

	@Specialization(guards = "proc.callTarget == cachedCallTarget")
	protected Object callDirect(VirtualFrame frame, OzProc proc, Object[] arguments,
			@Cached("proc.callTarget") RootCallTarget cachedCallTarget,
			@Cached("create(cachedCallTarget)") DirectCallNode callNode) {
		return callNode.call(frame, OzArguments.pack(proc.declarationFrame, arguments));
	}

	@Specialization
	protected Object callIndirect(VirtualFrame frame, OzProc proc, Object[] arguments,
			@Cached("create()") IndirectCallNode callNode) {
		return callNode.call(frame, proc.callTarget, OzArguments.pack(proc.declarationFrame, arguments));
	}

}

@@ -889,39 +889,408 @@
 proc
-.callTarget == cachedCallTarget
+ == cachedProc%22)%0A%09protected Object callProcIdentity(VirtualFrame frame, OzProc proc, Object%5B%5D arguments,%0A%09%09%09@Cached(%22proc%22) OzProc cachedProc,%0A%09%09%09@Cached(%22create(cachedProc.callTarget)%22) DirectCallNode callNode) %7B%0A%09%09return callNode.call(frame, OzArguments.pack(cachedProc.declarationFrame, arguments));%0A%09%7D%0A%0A%09@Specialization(guards = %22proc.callTarget == cachedCallTarget%22, contains = %22callProcIdentity
 %22)%0A%09

Optimize calls based on procedure identity