private FunctionEndPoint GetCompliantFEP( Context context, List<StackValue> arguments, FunctionGroup funcGroup, List<ReplicationInstruction> replicationInstructions, StackFrame stackFrame, RuntimeCore runtimeCore, bool allowArrayPromotion = false) { Dictionary<FunctionEndPoint, int> candidatesWithDistances = funcGroup.GetConversionDistances( context, arguments, replicationInstructions, runtimeCore.DSExecutable.classTable, runtimeCore, allowArrayPromotion); Dictionary<FunctionEndPoint, int> candidatesWithCastDistances = funcGroup.GetCastDistances( context, arguments, replicationInstructions, runtimeCore.DSExecutable.classTable, runtimeCore); List<FunctionEndPoint> candidateFunctions = GetCandidateFunctions(stackFrame, candidatesWithDistances); FunctionEndPoint compliantTarget = GetCompliantTarget( context, arguments, replicationInstructions, stackFrame, runtimeCore, candidatesWithCastDistances, candidateFunctions, candidatesWithDistances); return compliantTarget; }
private void ComputeFeps(StringBuilder log, ProtoCore.Runtime.Context context, List<StackValue> arguments, FunctionGroup funcGroup, ReplicationControl replicationControl, List<List<ProtoCore.ReplicationGuide>> partialReplicationGuides, StackFrame stackFrame, Core core, out List<FunctionEndPoint> resolvesFeps, out List<ReplicationInstruction> replicationInstructions) { //With replication guides only //Exact match //Match with single elements //Match with single elements with upcast //Try replication without type cast //Match with type conversion //Match with type conversion with upcast //Try replication + type casting //Try replication + type casting + Array promotion #region First Case: Replicate only according to the replication guides { log.AppendLine("Case 1: Exact Match"); FunctionEndPoint fep = Case1GetCompleteMatchFEP(context, arguments, funcGroup, replicationControl, stackFrame, core, log); if (fep != null) { //log.AppendLine("Resolution completed in " + sw.ElapsedMilliseconds + "ms"); if (core.Options.DumpFunctionResolverLogic) core.DSExecutable.EventSink.PrintMessage(log.ToString()); resolvesFeps = new List<FunctionEndPoint>() { fep }; replicationInstructions = replicationControl.Instructions; return; } } #endregion #region Case 2: Replication with no type cast { log.AppendLine("Case 2: Beginning Auto-replication, no casts"); //Build the possible ways in which we might replicate List<List<ReplicationInstruction>> replicationTrials = Replicator.BuildReplicationCombinations(replicationControl.Instructions, arguments, core); foreach (List<ReplicationInstruction> replicationOption in replicationTrials) { ReplicationControl rc = new ReplicationControl() { Instructions = replicationOption }; log.AppendLine("Attempting replication control: " + rc); List<List<StackValue>> reducedParams = Replicator.ComputeAllReducedParams(arguments, rc.Instructions, core); int resolutionFailures; Dictionary<FunctionEndPoint, int> lookups = funcGroup.GetExactMatchStatistics( context, reducedParams, stackFrame, core, out resolutionFailures); if (resolutionFailures > 0) continue; log.AppendLine("Resolution succeeded against FEP Cluster"); foreach (FunctionEndPoint fep in lookups.Keys) log.AppendLine("\t - " + fep); List<FunctionEndPoint> feps = new List<FunctionEndPoint>(); feps.AddRange(lookups.Keys); //log.AppendLine("Resolution completed in " + sw.ElapsedMilliseconds + "ms"); if (core.Options.DumpFunctionResolverLogic) core.DSExecutable.EventSink.PrintMessage(log.ToString()); //Otherwise we have a cluster of FEPs that can be used to dispatch the array resolvesFeps = feps; replicationInstructions = rc.Instructions; return; } } #endregion #region Case 3: Match with type conversion, but no array promotion { log.AppendLine("Case 3: Type conversion"); Dictionary<FunctionEndPoint, int> candidatesWithDistances = funcGroup.GetConversionDistances(context, arguments, replicationControl.Instructions, core.ClassTable, core); Dictionary<FunctionEndPoint, int> candidatesWithCastDistances = funcGroup.GetCastDistances(context, arguments, replicationControl.Instructions, core.ClassTable, core); List<FunctionEndPoint> candidateFunctions = GetCandidateFunctions(stackFrame, candidatesWithDistances); FunctionEndPoint compliantTarget = GetCompliantTarget(context, arguments, replicationControl.Instructions, stackFrame, core, candidatesWithCastDistances, candidateFunctions, candidatesWithDistances); if (compliantTarget != null) { log.AppendLine("Resolution Succeeded: " + compliantTarget); if (core.Options.DumpFunctionResolverLogic) core.DSExecutable.EventSink.PrintMessage(log.ToString()); resolvesFeps = new List<FunctionEndPoint>() { compliantTarget }; replicationInstructions = replicationControl.Instructions; return; } } #endregion #region Case 4: Match with type conversion and replication log.AppendLine("Case 4: Replication + Type conversion"); { if (arguments.Any(arg => arg.IsArray)) { //Build the possible ways in which we might replicate List<List<ReplicationInstruction>> replicationTrials = Replicator.BuildReplicationCombinations(replicationControl.Instructions, arguments, core); foreach (List<ReplicationInstruction> replicationOption in replicationTrials) { ReplicationControl rc = new ReplicationControl() { Instructions = replicationOption }; log.AppendLine("Attempting replication control: " + rc); //@TODO: THis should use the proper reducer? Dictionary<FunctionEndPoint, int> candidatesWithDistances = funcGroup.GetConversionDistances(context, arguments, rc.Instructions, core.ClassTable, core); Dictionary<FunctionEndPoint, int> candidatesWithCastDistances = funcGroup.GetCastDistances(context, arguments, rc.Instructions, core.ClassTable, core); List<FunctionEndPoint> candidateFunctions = GetCandidateFunctions(stackFrame, candidatesWithDistances); FunctionEndPoint compliantTarget = GetCompliantTarget(context, arguments, rc.Instructions, stackFrame, core, candidatesWithCastDistances, candidateFunctions, candidatesWithDistances); if (compliantTarget != null) { log.AppendLine("Resolution Succeeded: " + compliantTarget); if (core.Options.DumpFunctionResolverLogic) core.DSExecutable.EventSink.PrintMessage(log.ToString()); resolvesFeps = new List<FunctionEndPoint>() { compliantTarget }; replicationInstructions = rc.Instructions; return; } } } } #endregion #region Case 5: Match with type conversion, replication and array promotion log.AppendLine("Case 5: Replication + Type conversion + Array promotion"); { //Build the possible ways in which we might replicate List<List<ReplicationInstruction>> replicationTrials = Replicator.BuildReplicationCombinations(replicationControl.Instructions, arguments, core); //Add as a first attempt a no-replication, but allowing up-promoting replicationTrials.Insert(0, new List<ReplicationInstruction>() ); foreach (List<ReplicationInstruction> replicationOption in replicationTrials) { ReplicationControl rc = new ReplicationControl() { Instructions = replicationOption }; log.AppendLine("Attempting replication control: " + rc); //@TODO: THis should use the proper reducer? Dictionary<FunctionEndPoint, int> candidatesWithDistances = funcGroup.GetConversionDistances(context, arguments, rc.Instructions, core.ClassTable, core, true); Dictionary<FunctionEndPoint, int> candidatesWithCastDistances = funcGroup.GetCastDistances(context, arguments, rc.Instructions, core.ClassTable, core); List<FunctionEndPoint> candidateFunctions = GetCandidateFunctions(stackFrame, candidatesWithDistances); FunctionEndPoint compliantTarget = GetCompliantTarget(context, arguments, rc.Instructions, stackFrame, core, candidatesWithCastDistances, candidateFunctions, candidatesWithDistances); if (compliantTarget != null) { log.AppendLine("Resolution Succeeded: " + compliantTarget); if (core.Options.DumpFunctionResolverLogic) core.DSExecutable.EventSink.PrintMessage(log.ToString()); resolvesFeps = new List<FunctionEndPoint>() { compliantTarget }; replicationInstructions = rc.Instructions; return; } } } #endregion resolvesFeps = new List<FunctionEndPoint>(); replicationInstructions = replicationControl.Instructions; }