package scala.runtime;

import java.dyn.CallSite;
import java.dyn.MethodHandle;

/**
 * This class resolves calls through refinement types. The
 * bootstrap method is called when an invokedynamic is found
 * by the Java VM.
 * 
 * Note: Requires Java 7 with invoke dynamic support (see JSR 292)
 *
 * @author Iulian Dragos
 * @see JSR292
 */
public class DynamicDispatch {

    /**
     * Resolve an invoke dynamic in Scala code. invokedynamic calls appear
     * when a method defined by a refinement type is called. It is resolved
     * by looking up a method with the same name and types in the receiver
     * object. It is guaranteed by the type checker that such a method 
     * exists.
     *
     * The current implementation is not correct, a call site being 
     * always bootstrapped to a method handle. A bound call site should be
     * guarded by a test on the receiver type. Such code should either
     * be generated by the compiler, or by this bootstrap method using
     * one of the code combinators provided in java.dyn.*. 
     *
     * ATM, they are not yet available in the JVM.
     */
    public static Object bootstrapInvokeDynamic(CallSite cs, Object... args) {
        println(cs);
        
        MethodHandle mh = MethodHandles.findVirtual(cs.callerClass(),
                                                    cs.name(),
                                                    cs.type());
        cs.setTarget(mh);
        return mh(args);
    }
}
