Beispiel #1
0
        /// <summary>
        /// For a given list of formal parameters, get the function end points that resolve
        /// </summary>
        /// <param name="context"></param>
        /// <param name="formalParams"></param>
        /// <param name="replicationInstructions"></param>
        /// <param name="stackFrame"></param>
        /// <param name="core"></param>
        /// <param name="unresolvable">The number of argument sets that couldn't be resolved</param>
        /// <returns>Returns true, if it can find a matching FEP for all the reduced params. Returns False otherwise.</returns>
        public bool CanGetExactMatchStatics(
            Runtime.Context context,
            List <List <StackValue> > reducedFormalParams,
            StackFrame stackFrame,
            RuntimeCore runtimeCore,
            out HashSet <FunctionEndPoint> lookup)
        {
            lookup = new HashSet <FunctionEndPoint>();

            if (reducedFormalParams.Count == 0)
            {
                return(false);
            }

            foreach (List <StackValue> formalParamSet in reducedFormalParams)
            {
                List <FunctionEndPoint> feps = GetExactTypeMatches(context, formalParamSet, new List <ReplicationInstruction>(), stackFrame, runtimeCore);
                if (feps.Count == 0)
                {
                    return(false);
                }

                foreach (FunctionEndPoint fep in feps)
                {
                    lookup.Add(fep);
                }
            }

            return(true);
        }
Beispiel #2
0
        /// <summary>
        /// For a given list of formal parameters, get the function end points that resolve
        /// </summary>
        /// <param name="context"></param>
        /// <param name="formalParams"></param>
        /// <param name="replicationInstructions"></param>
        /// <param name="stackFrame"></param>
        /// <param name="core"></param>
        /// <param name="unresolvable">The number of argument sets that couldn't be resolved</param>
        /// <returns></returns>
        public Dictionary <FunctionEndPoint, int> GetExactMatchStatistics(
            Runtime.Context context,
            List <List <StackValue> > reducedFormalParams, StackFrame stackFrame, RuntimeCore runtimeCore, out int unresolvable)
        {
            List <ReplicationInstruction> replicationInstructions = new List <ReplicationInstruction>(); //We've already done the reduction before calling this

            unresolvable = 0;
            Dictionary <FunctionEndPoint, int> ret = new Dictionary <FunctionEndPoint, int>();

            foreach (List <StackValue> formalParamSet in reducedFormalParams)
            {
                List <FunctionEndPoint> feps = GetExactTypeMatches(context,
                                                                   formalParamSet, replicationInstructions, stackFrame,
                                                                   runtimeCore);
                if (feps.Count == 0)
                {
                    //We have an arugment set that couldn't be resolved
                    unresolvable++;
                }

                foreach (FunctionEndPoint fep in feps)
                {
                    if (ret.ContainsKey(fep))
                    {
                        ret[fep]++;
                    }
                    else
                    {
                        ret.Add(fep, 1);
                    }
                }
            }

            return(ret);
        }
Beispiel #3
0
        /// <summary>
        /// Returns a dictionary of the function end points that are type compatible
        /// with any branch of replicated parameters.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="formalParams"></param>
        /// <param name="replicationInstructions"></param>
        /// <param name="classTable"></param>
        /// <param name="runtimeCore"></param>
        /// <returns></returns>
        public Dictionary <FunctionEndPoint, int> GetLooseConversionDistances(
            Runtime.Context context,
            List <StackValue> formalParams,
            List <ReplicationInstruction> replicationInstructions,
            ClassTable classTable,
            RuntimeCore runtimeCore)
        {
            Dictionary <FunctionEndPoint, int> ret = new Dictionary <FunctionEndPoint, int>();
            var reducedParams = Replicator.ComputeAllReducedParams(formalParams, replicationInstructions, runtimeCore);

            foreach (FunctionEndPoint fep in FunctionEndPoints)
            {
                foreach (var reducedParam in reducedParams)
                {
                    int distance = fep.GetConversionDistance(reducedParam, classTable, true, runtimeCore);
                    if (distance != (int)ProcedureDistance.InvalidDistance)
                    {
                        ret.Add(fep, distance);
                        break;
                    }
                }
            }

            return(ret);
        }
Beispiel #4
0
        /// <summary>
        /// Get a dictionary of the function end points that are type compatible
        /// with the costs of the associated conversions
        /// </summary>
        /// <param name="context"></param>
        /// <param name="formalParams"></param>
        /// <param name="replicationInstructions"></param>
        /// <returns></returns>
        public Dictionary <FunctionEndPoint, int> GetConversionDistances(Runtime.Context context,
                                                                         List <StackValue> formalParams, List <ReplicationInstruction> replicationInstructions,
                                                                         ClassTable classTable, RuntimeCore runtimeCore, bool allowArrayPromotion = false)
        {
            Dictionary <FunctionEndPoint, int> ret = new Dictionary <FunctionEndPoint, int>();

            //@PERF: Consider parallelising this
            List <FunctionEndPoint> feps            = FunctionEndPoints;
            List <StackValue>       reducedParamSVs = Replicator.EstimateReducedParams(formalParams, replicationInstructions, runtimeCore);

            foreach (FunctionEndPoint fep in feps)
            {
                int distance = fep.GetConversionDistance(reducedParamSVs, classTable, allowArrayPromotion, runtimeCore);
                if (distance !=
                    (int)ProcedureDistance.InvalidDistance)
                {
                    ret.Add(fep, distance);
                }
            }

            return(ret);
        }
Beispiel #5
0
        private StackValue Execute(
            List<FunctionEndPoint> functionEndPoint, 
            Context c, 
            List<StackValue> formalParameters, 
            List<ReplicationInstruction> replicationInstructions, 
            StackFrame stackFrame, 
            RuntimeCore runtimeCore, 
            FunctionGroup funcGroup)
        {
            SingleRunTraceData singleRunTraceData = (invokeCount < traceData.Count) ? traceData[invokeCount] : new SingleRunTraceData();
            SingleRunTraceData newTraceData = new SingleRunTraceData();
            StackValue ret;

            if (replicationInstructions.Count == 0)
            {
                c.IsReplicating = false;
                ret = ExecWithZeroRI(functionEndPoint, c, formalParameters, stackFrame, runtimeCore, funcGroup,
                    singleRunTraceData, newTraceData);
            }
            else //replicated call
            {
                c.IsReplicating = true;
                ret = ExecWithRISlowPath(functionEndPoint, c, formalParameters, replicationInstructions, stackFrame,
                                         runtimeCore, funcGroup, singleRunTraceData, newTraceData);
            }

            //Do a trace save here
            if (invokeCount < traceData.Count)
            {
                traceData[invokeCount] = newTraceData;
            }
            else
            {
                traceData.Add(newTraceData);
            }

            invokeCount++; //We've completed this invocation
            return ret;
        }
Beispiel #6
0
        //Dispatch
        private StackValue DispatchNew(
            Context context, 
            List<StackValue> arguments, 
            List<List<ReplicationGuide>> partialReplicationGuides, 
            List<AtLevel> atLevels,
            StackFrame stackFrame, RuntimeCore runtimeCore)
        {
            // Update the CallsiteExecutionState with 
            // TODO: Replace this with the real data
            UpdateCallsiteExecutionState(null, runtimeCore);

            Stopwatch sw = new Stopwatch();
            sw.Start();

            StringBuilder log = new StringBuilder();

            log.AppendLine("Method name: " + methodName);

            #region Get Function Group

            //@PERF: Possible optimisation point here, to deal with static dispatches that don't need replication analysis
            //Handle resolution Pass 1: Name -> Method Group
            FunctionGroup funcGroup = GetFuncGroup(runtimeCore);
            if (funcGroup == null)
            {
                log.AppendLine("Function group not located");
                log.AppendLine("Resolution failed in: " + sw.ElapsedMilliseconds);

                if (runtimeCore.Options.DumpFunctionResolverLogic)
                    runtimeCore.DSExecutable.EventSink.PrintMessage(log.ToString());

                return ReportFunctionGroupNotFound(runtimeCore, arguments);
            }

            //check accesibility of function group
            bool methodAccessible = IsFunctionGroupAccessible(runtimeCore, ref funcGroup);
            if (!methodAccessible)
            {
                return ReportMethodNotAccessible(runtimeCore);
            }

            //If we got here then the function group got resolved
            log.AppendLine("Function group resolved: " + funcGroup);

            #endregion

            arguments = GetArgumentsAtLevels(arguments, atLevels, runtimeCore).Select(a => a.Argument).ToList();

            partialReplicationGuides = PerformRepGuideDemotion(arguments, partialReplicationGuides, runtimeCore);

            //Replication Control is an ordered list of the elements that we have to replicate over
            //Ordering implies containment, so element 0 is the outer most forloop, element 1 is nested within it etc.
            //Take the explicit replication guides and build the replication structure
            //Turn the replication guides into a guide -> List args data structure
           var partialInstructions = Replicator.BuildPartialReplicationInstructions(partialReplicationGuides);

            //Get the fep that are resolved
            List<FunctionEndPoint> resolvesFeps;
            List<ReplicationInstruction> replicationInstructions;

            arguments = PerformRepGuideForcedPromotion(arguments, partialReplicationGuides, runtimeCore);
            ComputeFeps(log, context, arguments, funcGroup, partialInstructions, partialReplicationGuides, stackFrame, runtimeCore, out resolvesFeps, out replicationInstructions);

            if (resolvesFeps.Count == 0)
            {
                log.AppendLine("Resolution Failed");

                if (runtimeCore.Options.DumpFunctionResolverLogic)
                    runtimeCore.DSExecutable.EventSink.PrintMessage(log.ToString());

                return ReportMethodNotFoundForArguments(runtimeCore, arguments);
            }

            arguments.ForEach(x => runtimeCore.AddCallSiteGCRoot(CallSiteID, x));
            StackValue ret = Execute(resolvesFeps, context, arguments, replicationInstructions, stackFrame, runtimeCore, funcGroup);
            runtimeCore.RemoveCallSiteGCRoot(CallSiteID);
            return ret;
        }
Beispiel #7
0
        public StackValue JILDispatch(
            List<StackValue> arguments, 
            List<List<ReplicationGuide>> replicationGuides,
            List<AtLevel> atLevels, 
            StackFrame stackFrame, 
            RuntimeCore runtimeCore, 
            Context context)
        {
#if DEBUG

            ArgumentSanityCheck(arguments);
#endif
            // Dispatch method
            return DispatchNew(context, arguments, replicationGuides, atLevels, stackFrame, runtimeCore);
        }
Beispiel #8
0
        private void ComputeFeps(
            Context context, 
            List<StackValue> arguments,
            FunctionGroup funcGroup,
            List<ReplicationInstruction> instructions, 
            StackFrame stackFrame,
            RuntimeCore runtimeCore,
            out List<FunctionEndPoint> resolvesFeps,
            out List<ReplicationInstruction> replicationInstructions)
        {
            #region Case 1: Replication guide with exact match 
            {
                FunctionEndPoint fep = GetCompleteMatchFunctionEndPoint(context, arguments, funcGroup, instructions, stackFrame, runtimeCore);
                if (fep != null)
                {
                    resolvesFeps = new List<FunctionEndPoint>() { fep };
                    replicationInstructions = instructions;
                    return;
                }
            }
            #endregion

            var replicationTrials = Replicator.BuildReplicationCombinations(instructions, arguments, runtimeCore);

            #region Case 2: Replication and replication guide with exact match
            {
                //Build the possible ways in which we might replicate
                foreach (List<ReplicationInstruction> replicationOption in replicationTrials)
                {
                    List<List<StackValue>> reducedParams = Replicator.ComputeAllReducedParams(arguments, replicationOption, runtimeCore);
                    HashSet<FunctionEndPoint> lookups;
                    if (funcGroup.CanGetExactMatchStatics(context, reducedParams, stackFrame, runtimeCore, out lookups))
                    {
                        //Otherwise we have a cluster of FEPs that can be used to dispatch the array
                        resolvesFeps = new List<FunctionEndPoint>(lookups);
                        replicationInstructions = replicationOption;
                        return;
                    }
                }

            }
            #endregion

            #region Case 3: Replciation with type conversion
            {
                FunctionEndPoint compliantTarget = GetCompliantFEP(context, arguments, funcGroup, instructions, stackFrame, runtimeCore);
                if (compliantTarget != null)
                {
                    resolvesFeps = new List<FunctionEndPoint>() { compliantTarget };
                    replicationInstructions = instructions;
                    return;
                }
            }
            #endregion

            #region Case 4: Replication and replication guide with type conversion
            {
                if (arguments.Any(arg => arg.IsArray))
                {
                    foreach (List<ReplicationInstruction> replicationOption in replicationTrials)
                    {
                        FunctionEndPoint compliantTarget = GetCompliantFEP(context, arguments, funcGroup, replicationOption, stackFrame, runtimeCore);
                        if (compliantTarget != null)
                        {
                            resolvesFeps = new List<FunctionEndPoint>() { compliantTarget };
                            replicationInstructions = replicationOption;
                            return;
                        }
                    }
                }
            }

            #endregion

            #region Case 5: Replication and replciation guide with type conversion and array promotion
            {
                //Add as a first attempt a no-replication, but allowing up-promoting
                replicationTrials.Add(new List<ReplicationInstruction>());

                foreach (List<ReplicationInstruction> replicationOption in replicationTrials)
                {
                    FunctionEndPoint compliantTarget = GetCompliantFEP(context, arguments, funcGroup, replicationOption, stackFrame, runtimeCore, true);
                    if (compliantTarget != null)
                    {
                        resolvesFeps = new List<FunctionEndPoint>() { compliantTarget };
                        replicationInstructions = replicationOption;
                        return;
                    }
                }
            }
            #endregion

            #region Case 6: Replication and replication guide with type conversion and array promotion, and OK if not all convertible
            {
                foreach (List<ReplicationInstruction> replicationOption in replicationTrials)
                {
                    FunctionEndPoint compliantTarget = GetLooseCompliantFEP(context, arguments, funcGroup, replicationOption, stackFrame, runtimeCore);
                    if (compliantTarget != null)
                    {
                        resolvesFeps = new List<FunctionEndPoint>() { compliantTarget };
                        replicationInstructions = replicationOption;
                        return;
                    }
                }
            }
            #endregion

            resolvesFeps = new List<FunctionEndPoint>();
            replicationInstructions = instructions;
        }
Beispiel #9
0
 public void SetProperties(Options runtimeOptions, Executable executable, DebugProperties debugProps = null, ProtoCore.Runtime.Context context = null, Executable exprInterpreterExe = null)
 {
     this.Context            = context;
     this.DSExecutable       = executable;
     this.Options            = runtimeOptions;
     this.DebugProps         = debugProps;
     this.ExprInterpreterExe = exprInterpreterExe;
 }
Beispiel #10
0
        private void ComputeFeps(
            StringBuilder log, 
            Context context, 
            List<StackValue> arguments,
            FunctionGroup funcGroup,
            List<ReplicationInstruction> instructions, 
            List<List<ReplicationGuide>> partialReplicationGuides,
            StackFrame stackFrame,
            RuntimeCore runtimeCore,
            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, instructions,
                                                                stackFrame,
                                                                runtimeCore, log);
                if (fep != null)
                {
                    if (runtimeCore.Options.DumpFunctionResolverLogic)
                        runtimeCore.DSExecutable.EventSink.PrintMessage(log.ToString());

                    resolvesFeps = new List<FunctionEndPoint>() { fep };
                    replicationInstructions = instructions;

                    return;
                }
            }

            #endregion

            #region Case 1a: Replicate only according to the replication guides, but with a sub-typing match
            {
                log.AppendLine("Case 1a: Replication guides + auto-replication + no cases");
                List<List<StackValue>> reducedParams = Replicator.ComputeAllReducedParams(arguments, instructions, runtimeCore);
                int resolutionFailures;

                Dictionary<FunctionEndPoint, int> lookups = funcGroup.GetExactMatchStatistics(
                    context, reducedParams, stackFrame, runtimeCore,
                    out resolutionFailures);

                if (resolutionFailures == 0)
                {
                    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);

                    if (runtimeCore.Options.DumpFunctionResolverLogic)
                        runtimeCore.DSExecutable.EventSink.PrintMessage(log.ToString());

                    //Otherwise we have a cluster of FEPs that can be used to dispatch the array
                    resolvesFeps = feps;
                    replicationInstructions = instructions;

                    return;
                }
            }

            #endregion


            var replicationTrials = Replicator.BuildReplicationCombinations(instructions, arguments, runtimeCore);
            #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
                foreach (List<ReplicationInstruction> repOption in replicationTrials)
                {
                    List<List<StackValue>> reducedParams = Replicator.ComputeAllReducedParams(arguments, repOption, runtimeCore);
                    int resolutionFailures;

                    Dictionary<FunctionEndPoint, int> lookups = funcGroup.GetExactMatchStatistics(
                        context, reducedParams, stackFrame, runtimeCore,
                        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);

                    if (runtimeCore.Options.DumpFunctionResolverLogic)
                        runtimeCore.DSExecutable.EventSink.PrintMessage(log.ToString());

                    //Otherwise we have a cluster of FEPs that can be used to dispatch the array
                    resolvesFeps = feps;
                    replicationInstructions = repOption;

                    return;
                }
            }

            #endregion

            #region Case 3: Match with type conversion, but no array promotion
            {
                log.AppendLine("Case 3: Type conversion");

                FunctionEndPoint compliantTarget = GetCompliantFEP(context, arguments, funcGroup, instructions, stackFrame, runtimeCore);

                if (compliantTarget != null)
                {
                    log.AppendLine("Resolution Succeeded: " + compliantTarget);

                    if (runtimeCore.Options.DumpFunctionResolverLogic)
                        runtimeCore.DSExecutable.EventSink.PrintMessage(log.ToString());

                    resolvesFeps = new List<FunctionEndPoint>() { compliantTarget };
                    replicationInstructions = 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))
                {
                    foreach (List<ReplicationInstruction> replicationOption in replicationTrials)
                    {
                        //@TODO: THis should use the proper reducer?
                        FunctionEndPoint compliantTarget = GetCompliantFEP(context, arguments, funcGroup, replicationOption, stackFrame, runtimeCore);
                        if (compliantTarget != null)
                        {
                            log.AppendLine("Resolution Succeeded: " + compliantTarget);

                            if (runtimeCore.Options.DumpFunctionResolverLogic)
                                runtimeCore.DSExecutable.EventSink.PrintMessage(log.ToString());

                            resolvesFeps = new List<FunctionEndPoint>() { compliantTarget };
                            replicationInstructions = replicationOption;
                            return;
                        }
                    }
                }
            }

            #endregion

            #region Case 5: Match with type conversion, replication and array promotion

            log.AppendLine("Case 5: Replication + Type conversion + Array promotion");
            {
                //Add as a first attempt a no-replication, but allowing up-promoting
                replicationTrials.Insert(0, new List<ReplicationInstruction>());

                foreach (List<ReplicationInstruction> replicationOption in replicationTrials)
                {
                    //@TODO: THis should use the proper reducer?
                    FunctionEndPoint compliantTarget = GetCompliantFEP(context, arguments, funcGroup, replicationOption, stackFrame, runtimeCore, true);
                    if (compliantTarget != null)
                    {
                        log.AppendLine("Resolution Succeeded: " + compliantTarget);

                        if (runtimeCore.Options.DumpFunctionResolverLogic)
                            runtimeCore.DSExecutable.EventSink.PrintMessage(log.ToString());
                        resolvesFeps = new List<FunctionEndPoint>() { compliantTarget };
                        replicationInstructions = replicationOption;
                        return;
                    }
                }
            }

            #endregion


            resolvesFeps = new List<FunctionEndPoint>();
            replicationInstructions = instructions;
        }
Beispiel #11
0
        /// <summary>
        /// Conservative guess as to whether this call will replicate or not
        /// This may give inaccurate answers if the node cluster doesn't actually exist
        /// </summary>
        /// <param name="context"></param>
        /// <param name="arguments"></param>
        /// <param name="stackFrame"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public bool WillCallReplicate(Context context, List<StackValue> arguments,
                                      List<List<ReplicationGuide>> partialReplicationGuides, StackFrame stackFrame, RuntimeCore runtimeCore,
                                      out List<List<ReplicationInstruction>> replicationTrials)
        {
            replicationTrials = new List<List<ReplicationInstruction>>();

            if (partialReplicationGuides.Count > 0)
            {
                // Jun Comment: And at least one of them contains somthing
                for (int n = 0; n < partialReplicationGuides.Count; ++n)
                {
                    if (partialReplicationGuides[n].Count > 0)
                    {
                        return true;
                    }
                }
            }

            #region Get Function Group

            //@PERF: Possible optimisation point here, to deal with static dispatches that don't need replication analysis
            //Handle resolution Pass 1: Name -> Method Group
            FunctionGroup funcGroup;
            try
            {
                funcGroup = globalFunctionTable.GlobalFuncTable[classScope + 1][methodName];
            }
            catch (KeyNotFoundException)
            {
                return false;
            }

            #endregion

            //Replication Control is an ordered list of the elements that we have to replicate over
            //Ordering implies containment, so element 0 is the outer most forloop, element 1 is nested within it etc.
            //Take the explicit replication guides and build the replication structure
            //Turn the replication guides into a guide -> List args data structure
           var instructions = Replicator.BuildPartialReplicationInstructions(partialReplicationGuides);

            #region First Case: Replicate only according to the replication guides

            {
                FunctionEndPoint fep = Case1GetCompleteMatchFEP(context, arguments, funcGroup, instructions,
                                                                stackFrame,
                                                                runtimeCore, new StringBuilder());
                if (fep != null)
                {
                    //found an exact match
                    return false;
                }
            }

            #endregion

            #region Case 2: Replication with no type cast

            {
                //Build the possible ways in which we might replicate
                replicationTrials = Replicator.BuildReplicationCombinations(instructions, arguments, runtimeCore);

                foreach (List<ReplicationInstruction> replicationOption in replicationTrials)
                {
                    List<List<StackValue>> reducedParams = Replicator.ComputeAllReducedParams(arguments, replicationOption, runtimeCore);
                    int resolutionFailures;

                    funcGroup.GetExactMatchStatistics(context, reducedParams, stackFrame, runtimeCore, out resolutionFailures);

                    if (resolutionFailures > 0)
                        continue;

                    return true; //Replicates against cluster
                }
            }

            #endregion

            #region Case 3: Match with type conversion, but no array promotion

            {
                Dictionary<FunctionEndPoint, int> candidatesWithDistances =
                    funcGroup.GetConversionDistances(context, arguments, instructions,
                                                     runtimeCore.DSExecutable.classTable, runtimeCore);
                Dictionary<FunctionEndPoint, int> candidatesWithCastDistances =
                    funcGroup.GetCastDistances(context, arguments, instructions, runtimeCore.DSExecutable.classTable,
                                               runtimeCore);

                List<FunctionEndPoint> candidateFunctions = GetCandidateFunctions(stackFrame, candidatesWithDistances);
                FunctionEndPoint compliantTarget = GetCompliantTarget(context, arguments,
                                                                      instructions, stackFrame, runtimeCore,
                                                                      candidatesWithCastDistances, candidateFunctions,
                                                                      candidatesWithDistances);

                if (compliantTarget != null)
                {
                    return false; //Type conversion but no replication
                }
            }

            #endregion

            #region Case 5: Match with type conversion, replication and array promotion

            {
                //Build the possible ways in which we might replicate
                replicationTrials =
                    Replicator.BuildReplicationCombinations(instructions, arguments, runtimeCore);

                //Add as a first attempt a no-replication, but allowing up-promoting
                replicationTrials.Insert(0,
                                         new List<ReplicationInstruction>()
                    );
            }

            #endregion

            return true; //It'll replicate if it suceeds
        }
Beispiel #12
0
        private StackValue Execute(List<FunctionEndPoint> functionEndPoint, Context c,
                                   List<StackValue> formalParameters,
                                   List<ReplicationInstruction> replicationInstructions, StackFrame stackFrame,
                                   RuntimeCore runtimeCore, FunctionGroup funcGroup)
        {
            StackValue ret;

            if (replicationInstructions.Count == 0)
            {
                c.IsReplicating = false;


                SingleRunTraceData singleRunTraceData;
                //READ TRACE FOR NON-REPLICATED CALL
                //Lookup the trace data in the cache
                if (invokeCount < traceData.Count)
                {
                    singleRunTraceData = traceData[invokeCount];
                }
                else
                {
                    //We don't have any previous stored data for the previous invoke calls, so 
                    //gen an empty packet and push it through
                    singleRunTraceData = new SingleRunTraceData();
                }

                SingleRunTraceData newTraceData = new SingleRunTraceData();

                ret = ExecWithZeroRI(functionEndPoint, c, formalParameters, stackFrame, runtimeCore, funcGroup,
                    singleRunTraceData, newTraceData);


                //newTraceData is update with the trace cache assocaite with the single shot executions
                
                if (invokeCount < traceData.Count)
                    traceData[invokeCount] = newTraceData;
                else
                {
                    traceData.Add(newTraceData);
                }
                
            }
            else //replicated call
            {
                //Extract the correct run data from the trace cache here

                //This is the thing that will get unpacked from the datastore

                SingleRunTraceData singleRunTraceData;
                SingleRunTraceData newTraceData = new SingleRunTraceData();

                //Lookup the trace data in the cache
                if (invokeCount < traceData.Count)
                {
                    singleRunTraceData = traceData[invokeCount];
                }
                else
                {
                    //We don't have any previous stored data for the previous invoke calls, so 
                    //gen an empty packet and push it through
                    singleRunTraceData = new SingleRunTraceData();
                }


                c.IsReplicating = true;
                ret = ExecWithRISlowPath(functionEndPoint, c, formalParameters, replicationInstructions, stackFrame,
                                         runtimeCore, funcGroup, singleRunTraceData, newTraceData);

                //Do a trace save here
                if (invokeCount < traceData.Count)
                    traceData[invokeCount] = newTraceData;
                else
                {
                    traceData.Add(newTraceData);
                }
            }

            invokeCount++; //We've completed this invocation

            if (ret.IsNull)
                return ret; //It didn't return a value

            return ret;
        }
Beispiel #13
0
        //Dispatch
        private StackValue DispatchNew(Context context, List<StackValue> arguments,
                                      List<List<ReplicationGuide>> partialReplicationGuides, StackFrame stackFrame, RuntimeCore runtimeCore)
        {

            // Update the CallsiteExecutionState with 
            // TODO: Replace this with the real data
            UpdateCallsiteExecutionState(null, runtimeCore);

            Stopwatch sw = new Stopwatch();
            sw.Start();


            StringBuilder log = new StringBuilder();

            log.AppendLine("Method name: " + methodName);

            #region Get Function Group

            //@PERF: Possible optimisation point here, to deal with static dispatches that don't need replication analysis
            //Handle resolution Pass 1: Name -> Method Group
            FunctionGroup funcGroup = GetFuncGroup(runtimeCore);

            if (funcGroup == null)
            {
                log.AppendLine("Function group not located");
                log.AppendLine("Resolution failed in: " + sw.ElapsedMilliseconds);

                if (runtimeCore.Options.DumpFunctionResolverLogic)
                    runtimeCore.DSExecutable.EventSink.PrintMessage(log.ToString());

                return ReportFunctionGroupNotFound(runtimeCore);
            }


            //// Now that a function group is resolved, the callsite guid can be cached
            //if (null != funcGroup.CallsiteInstance)
            //{
            //    // Sanity check, if the callsite exists, then it mean the guid is identical to the cached guid
            //    Validity.Assert(funcGroup.CallsiteInstance.callsiteID == this.callsiteID);
            //}
            //else
            //{
            //    funcGroup.CallsiteInstance = this;
            //}

            //check accesibility of function group
            bool methodAccessible = IsFunctionGroupAccessible(runtimeCore, ref funcGroup);
            if (!methodAccessible)
                return ReportMethodNotAccessible(runtimeCore);

            //If we got here then the function group got resolved
            log.AppendLine("Function group resolved: " + funcGroup);

            #endregion

            partialReplicationGuides = PerformRepGuideDemotion(arguments, partialReplicationGuides, runtimeCore);


            //Replication Control is an ordered list of the elements that we have to replicate over
            //Ordering implies containment, so element 0 is the outer most forloop, element 1 is nested within it etc.
            //Take the explicit replication guides and build the replication structure
            //Turn the replication guides into a guide -> List args data structure
            ReplicationControl replicationControl =
                Replicator.Old_ConvertGuidesToInstructions(partialReplicationGuides);

            log.AppendLine("Replication guides processed to: " + replicationControl);

            //Get the fep that are resolved
            List<FunctionEndPoint> resolvesFeps;
            List<ReplicationInstruction> replicationInstructions;



            arguments = PerformRepGuideForcedPromotion(arguments, partialReplicationGuides, runtimeCore);


            ComputeFeps(log, context, arguments, funcGroup, replicationControl, partialReplicationGuides, stackFrame, runtimeCore, out resolvesFeps, out replicationInstructions);


            if (resolvesFeps.Count == 0)
            {
                log.AppendLine("Resolution Failed");

                if (runtimeCore.Options.DumpFunctionResolverLogic)
                    runtimeCore.DSExecutable.EventSink.PrintMessage(log.ToString());

                return ReportMethodNotFoundForArguments(runtimeCore, arguments);
            }

            StackValue ret = Execute(resolvesFeps, context, arguments, replicationInstructions, stackFrame, runtimeCore, funcGroup);

            return ret;
        }
Beispiel #14
0
        /// <summary>
        /// Returns complete match attempts to locate a function endpoint where 1 FEP matches all of the requirements for dispatch
        /// </summary>
        /// <param name="context"></param>
        /// <param name="arguments"></param>
        /// <param name="funcGroup"></param>
        /// <param name="replicationControl"></param>
        /// <param name="stackFrame"></param>
        /// <param name="core"></param>
        /// <param name="log"></param>
        /// <returns></returns>
        private FunctionEndPoint GetCompleteMatchFunctionEndPoint(
            Context context, List<StackValue> arguments,
            FunctionGroup funcGroup,
            List<ReplicationInstruction> replicationInstructions,
            StackFrame stackFrame,
            RuntimeCore runtimeCore)
        {
            //Exact match
            var exactTypeMatchingCandindates = funcGroup.GetExactTypeMatches(context, arguments, replicationInstructions, stackFrame, runtimeCore);

            if (exactTypeMatchingCandindates.Count == 0)
            {
                return null;
            }

            FunctionEndPoint fep = null;
            if (exactTypeMatchingCandindates.Count == 1)
            {
                //Exact match
                fep = exactTypeMatchingCandindates[0];
            }
            else
            {
                //Exact match with upcast
                fep = SelectFEPFromMultiple(stackFrame, runtimeCore, exactTypeMatchingCandindates, arguments);
            }

            return fep;
        }
Beispiel #15
0
        /// <summary>
        /// Excecute an arbitrary depth replication using the full slow path algorithm
        /// </summary>
        /// <param name="functionEndPoint"> </param>
        /// <param name="c"></param>
        /// <param name="formalParameters"></param>
        /// <param name="replicationInstructions"></param>
        /// <param name="stackFrame"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        private StackValue ExecWithRISlowPath(
            List<FunctionEndPoint> functionEndPoint, 
            Context c, 
            List<StackValue> formalParameters, 
            List<ReplicationInstruction> replicationInstructions, 
            StackFrame stackFrame, 
            RuntimeCore runtimeCore, 
            FunctionGroup funcGroup, 
            SingleRunTraceData previousTraceData, 
            SingleRunTraceData newTraceData)
        {
            if (runtimeCore.Options.ExecutionMode == ExecutionMode.Parallel)
                throw new NotImplementedException("Parallel mode disabled: {BF417AD5-9EA9-4292-ABBC-3526FC5A149E}");

            //Recursion base case
            if (replicationInstructions.Count == 0)
            {
                return ExecWithZeroRI(functionEndPoint, c, formalParameters, stackFrame, runtimeCore, funcGroup, previousTraceData, newTraceData);
            }

            //Get the replication instruction that this call will deal with
            ReplicationInstruction ri = replicationInstructions[0];

            if (ri.Zipped)
            {
                ZipAlgorithm algorithm = ri.ZipAlgorithm;

                //For each item in this plane, an array of the length of the minimum will be constructed

                //The size of the array will be the minimum size of the passed arrays
                List<int> repIndecies = ri.ZipIndecies;

                //this will hold the heap elements for all the arrays that are going to be replicated over
                List<StackValue[]> parameters = new List<StackValue[]>();

                int retSize;
                switch (algorithm)
                {
                    case ZipAlgorithm.Shortest:
                        retSize = Int32.MaxValue; //Search to find the smallest
                        break;

                    case ZipAlgorithm.Longest:
                        retSize = Int32.MinValue; //Search to find the largest
                        break;

                    default:
                        throw new ReplicationCaseNotCurrentlySupported(Resources.AlgorithmNotSupported);
                }


                bool hasEmptyArg = false;
                foreach (int repIndex in repIndecies)
                {

                    StackValue[] subParameters = null;
                    if (formalParameters[repIndex].IsArray)
                    {
                        subParameters = runtimeCore.Heap.ToHeapObject<DSArray>(formalParameters[repIndex]).Values.ToArray();
                    }
                    else
                    {
                        subParameters = new StackValue[] { formalParameters[repIndex] };
                    }
                    parameters.Add(subParameters);

                    if (subParameters.Length == 0)
                        hasEmptyArg = true;

                    switch (algorithm)
                    {
                        case ZipAlgorithm.Shortest:
                            retSize = Math.Min(retSize, subParameters.Length); //We need the smallest array
                            break;
                        case ZipAlgorithm.Longest:
                            retSize = Math.Max(retSize, subParameters.Length); //We need the longest array
                            break;
                    }

                }

                // If we're being asked to replicate across an empty list
                // then it's always going to be zero, as there will never be any
                // data to pass to that parameter.
                if (hasEmptyArg)
                    retSize = 0;

                StackValue[] retSVs = new StackValue[retSize];
                SingleRunTraceData retTrace = newTraceData;
                retTrace.NestedData = new List<SingleRunTraceData>(); //this will shadow the SVs as they are created

                //Populate out the size of the list with default values
                //@TODO:Luke perf optimisation here
                for (int i = 0; i < retSize; i++)
                    retTrace.NestedData.Add(new SingleRunTraceData());

                for (int i = 0; i < retSize; i++)
                {
                    SingleRunTraceData lastExecTrace = new SingleRunTraceData();

                    if (previousTraceData.HasNestedData && i < previousTraceData.NestedData.Count)
                    {
                        //There was previous data that needs loading into the cache
                        lastExecTrace = previousTraceData.NestedData[i];
                    }
                    else
                    {
                        //We're off the edge of the previous trace window
                        //So just pass in an empty block
                        lastExecTrace = new SingleRunTraceData();
                    }

                    //Build the call
                    List<StackValue> newFormalParams = new List<StackValue>();
                    newFormalParams.AddRange(formalParameters);

                    for (int repIi = 0; repIi < repIndecies.Count; repIi++)
                    {
                        switch (algorithm)
                        {
                            case ZipAlgorithm.Shortest:
                                //If the shortest algorithm is selected this would
                                newFormalParams[repIndecies[repIi]] = parameters[repIi][i];
                                break;
                            
                            case ZipAlgorithm.Longest:

                                int length = parameters[repIi].Length;
                                if (i < length)
                                {
                                    newFormalParams[repIndecies[repIi]] = parameters[repIi][i];
                                }
                                else
                                {
                                    newFormalParams[repIndecies[repIi]] = parameters[repIi].Last();
                                }
                                break;
                        }
                    }

                    List<ReplicationInstruction> newRIs = new List<ReplicationInstruction>();
                    newRIs.AddRange(replicationInstructions);
                    newRIs.RemoveAt(0);


                    SingleRunTraceData cleanRetTrace = new SingleRunTraceData();

                    retSVs[i] = ExecWithRISlowPath(functionEndPoint, c, newFormalParams, newRIs, stackFrame, runtimeCore,
                                                    funcGroup, lastExecTrace, cleanRetTrace);

                    runtimeCore.AddCallSiteGCRoot(CallSiteID, retSVs[i]);

                    retTrace.NestedData[i] = cleanRetTrace;
                }

                StackValue ret = runtimeCore.RuntimeMemory.Heap.AllocateArray(retSVs);
                return ret;
            }
            else
            {
                //With a cartesian product over an array, we are going to create an array of n
                //where the n is the product of the next item

                //We will call the subsequent reductions n times
                int cartIndex = ri.CartesianIndex;

                //this will hold the heap elements for all the arrays that are going to be replicated over
                bool supressArray = false;
                int retSize;
                StackValue[] parameters = null; 
                
                if (formalParameters[cartIndex].IsArray)
                {
                    DSArray array = runtimeCore.Heap.ToHeapObject<DSArray>(formalParameters[cartIndex]);
                    parameters = array.Values.ToArray();
                    retSize = parameters.Length;
                }
                else
                {
                    retSize = 1;
                    supressArray = true;
                }

                StackValue[] retSVs = new StackValue[retSize];

                SingleRunTraceData retTrace = newTraceData;
                retTrace.NestedData = new List<SingleRunTraceData>(); //this will shadow the SVs as they are created

                //Populate out the size of the list with default values
                //@TODO:Luke perf optimisation here
                for (int i = 0; i < retSize; i++)
                {
                    retTrace.NestedData.Add(new SingleRunTraceData());
                }

                if (supressArray)
                {
                    List<ReplicationInstruction> newRIs = new List<ReplicationInstruction>();
                    newRIs.AddRange(replicationInstructions);
                    newRIs.RemoveAt(0);

                    List<StackValue> newFormalParams = new List<StackValue>();
                    newFormalParams.AddRange(formalParameters);

                    return ExecWithRISlowPath(functionEndPoint, c, newFormalParams, newRIs, stackFrame, runtimeCore,
                                                funcGroup, previousTraceData, newTraceData);
                }

                //Now iterate over each of these options
                for (int i = 0; i < retSize; i++)
                {
                    //Build the call
                    List<StackValue> newFormalParams = new List<StackValue>();
                    newFormalParams.AddRange(formalParameters);

                    if (parameters != null)
                    {
                        //It was an array pack the arg with the current value
                        newFormalParams[cartIndex] = parameters[i];
                    }

                    List<ReplicationInstruction> newRIs = new List<ReplicationInstruction>();
                    newRIs.AddRange(replicationInstructions);
                    newRIs.RemoveAt(0);


                    SingleRunTraceData lastExecTrace;

                    if (previousTraceData.HasNestedData && i < previousTraceData.NestedData.Count)
                    {
                        //There was previous data that needs loading into the cache
                        lastExecTrace = previousTraceData.NestedData[i];
                    }
                    else if (previousTraceData.HasData && i == 0)
                    {
                        //We've moved up one dimension, and there was a previous run
                        lastExecTrace = new SingleRunTraceData();
                        lastExecTrace.Data = previousTraceData.GetLeftMostData();

                    }
                    else
                    {
                        //We're off the edge of the previous trace window
                        //So just pass in an empty block
                        lastExecTrace = new SingleRunTraceData();
                    }

                    //previousTraceData = lastExecTrace;
                    SingleRunTraceData cleanRetTrace = new SingleRunTraceData();

                    retSVs[i] = ExecWithRISlowPath(functionEndPoint, c, newFormalParams, newRIs, stackFrame, runtimeCore,
                                                    funcGroup, lastExecTrace, cleanRetTrace);

                    runtimeCore.AddCallSiteGCRoot(CallSiteID, retSVs[i]);

                    retTrace.NestedData[i] = cleanRetTrace;
                }


                StackValue ret = runtimeCore.RuntimeMemory.Heap.AllocateArray(retSVs);
                return ret;
            }
        }
Beispiel #16
0
        public static bool CompareFromDifferentCore(DSArray array1, DSArray array2, RuntimeCore rtCore1, RuntimeCore rtCore2, Context context = null)
        {
            if (array1.Count != array2.Count)
            {
                return false;
            }

            for (int i = 0; i < array1.Count; i++)
            {
                if (!StackUtils.CompareStackValues(array1.GetValueAt(i), array2.GetValueAt(i), rtCore1, rtCore2, context))
                {
                    return false;
                }
            }

            foreach (var key in array1.Dict.Keys)
            {
                StackValue value1 = array1.Dict[key];
                StackValue value2 = StackValue.Null;
                if (!array2.Dict.TryGetValue(key, out value2))
                {
                    return false;
                }

                if (!StackUtils.CompareStackValues(value1, value2, rtCore1, rtCore2))
                {
                    return false;
                }
            }

            return true;
        }
Beispiel #17
0
        //Single function call
        /// <summary>
        /// Dispatch without replication
        /// </summary>
        private StackValue ExecWithZeroRI(List<FunctionEndPoint> functionEndPoint, Context c,
                                          List<StackValue> formalParameters, StackFrame stackFrame, RuntimeCore runtimeCore,
                                          FunctionGroup funcGroup, SingleRunTraceData previousTraceData, SingleRunTraceData newTraceData)
        {
            if (runtimeCore.CancellationPending)
            {
                throw new ExecutionCancelledException();               
            }

            //@PERF: Todo add a fast path here for the case where we have a homogenious array so we can directly dispatch
            FunctionEndPoint finalFep = SelectFinalFep(c, functionEndPoint, formalParameters, stackFrame, runtimeCore);

            if (functionEndPoint == null)
            {
                runtimeCore.RuntimeStatus.LogWarning(WarningID.kMethodResolutionFailure, 
                    string.Format(Resources.FunctionDispatchFailed, "{2EB39E1B-557C-4819-94D8-CF7C9F933E8A}"));
                return StackValue.Null;
            }

            if (runtimeCore.Options.IDEDebugMode && runtimeCore.Options.RunMode != InterpreterMode.kExpressionInterpreter)
            {
                DebugFrame debugFrame = runtimeCore.DebugProps.DebugStackFrame.Peek();
                debugFrame.FinalFepChosen = finalFep;
            }

            List<StackValue> coercedParameters = finalFep.CoerceParameters(formalParameters, runtimeCore);

            // Correct block id where the function is defined. 
            stackFrame.FunctionBlock = finalFep.BlockScope;

            //TraceCache -> TLS
            //Extract left most high-D pack
            ISerializable traceD = previousTraceData.GetLeftMostData();

            if (traceD != null)
            {
                //There was data associated with the previous execution, push this into the TLS

                Dictionary<string, ISerializable> dataDict = new Dictionary<string, ISerializable>();
                dataDict.Add(TRACE_KEY, traceD);

                TraceUtils.SetObjectToTLS(dataDict);
            }
            else
            {
                //There was no trace data for this run
                TraceUtils.ClearAllKnownTLSKeys();
            }

            //EXECUTE
            StackValue ret = finalFep.Execute(c, coercedParameters, stackFrame, runtimeCore);

            if (ret.IsNull)
            {
                //wipe the trace cache
                TraceUtils.ClearTLSKey(TRACE_KEY);
            }

            //TLS -> TraceCache
            Dictionary<string, ISerializable> traceRet = TraceUtils.GetObjectFromTLS();

            if (traceRet.ContainsKey(TRACE_KEY))
            {
                var val = traceRet[TRACE_KEY];
                newTraceData.Data = val;
            }

            // An explicit call requires return coercion at the return instruction
            if (!ret.IsExplicitCall)
            {
                ret = PerformReturnTypeCoerce(finalFep, runtimeCore, ret);
            }
            return ret;
        }
Beispiel #18
0
        private FunctionEndPoint GetCompliantTarget(Context context, List<StackValue> formalParams,
                                                    List<ReplicationInstruction> replicationControl,
                                                    StackFrame stackFrame, RuntimeCore runtimeCore,
                                                    Dictionary<FunctionEndPoint, int> candidatesWithCastDistances,
                                                    List<FunctionEndPoint> candidateFunctions,
                                                    Dictionary<FunctionEndPoint, int> candidatesWithDistances)
        {
            FunctionEndPoint compliantTarget = null;
            //Produce an ordered list of the graph costs
            Dictionary<int, List<FunctionEndPoint>> conversionCostList = new Dictionary<int, List<FunctionEndPoint>>();

            foreach (FunctionEndPoint fep in candidateFunctions)
            {
                int cost = candidatesWithDistances[fep];
                if (conversionCostList.ContainsKey(cost))
                    conversionCostList[cost].Add(fep);
                else
                    conversionCostList.Add(cost, new List<FunctionEndPoint> {fep});
            }

            List<int> conversionCosts = new List<int>(conversionCostList.Keys);
            conversionCosts.Sort();

            List<FunctionEndPoint> fepsToSplit = new List<FunctionEndPoint>();

            foreach (int cost in conversionCosts)
            {
                foreach (FunctionEndPoint funcFep in conversionCostList[cost])
                {
                    if (funcFep.DoesPredicateMatch(context, formalParams, replicationControl))
                    {
                        compliantTarget = funcFep;
                        fepsToSplit.Add(funcFep);
                    }
                }

                if (compliantTarget != null)
                    break;
            }

            if (fepsToSplit.Count > 1)
            {
                int lowestCost = candidatesWithCastDistances[fepsToSplit[0]];
                compliantTarget = fepsToSplit[0];

                List<FunctionEndPoint> lowestCostFeps = new List<FunctionEndPoint>();

                foreach (FunctionEndPoint fep in fepsToSplit)
                {
                    if (candidatesWithCastDistances[fep] < lowestCost)
                    {
                        lowestCost = candidatesWithCastDistances[fep];
                        compliantTarget = fep;
                        lowestCostFeps = new List<FunctionEndPoint>() { fep };
                    }
                    else if (candidatesWithCastDistances[fep] == lowestCost)
                    {
                        lowestCostFeps.Add(fep);
                    }
                }

                //We have multiple feps, e.g. form overriding
                if (lowestCostFeps.Count > 0)
                    compliantTarget = SelectFEPFromMultiple(stackFrame, runtimeCore, lowestCostFeps, formalParams);
            }
            return compliantTarget;
        }
Beispiel #19
0
        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;
        }
Beispiel #20
0
        private FunctionEndPoint SelectFinalFep(Context context,
                                                List<FunctionEndPoint> functionEndPoint,
                                                List<StackValue> formalParameters, StackFrame stackFrame, RuntimeCore runtimeCore)
        {
            List<ReplicationInstruction> replicationControl = new List<ReplicationInstruction>();
            //We're never going to replicate so create an empty structure to allow us to use
            //the existing utility methods

            //Filter for exact matches

            List<FunctionEndPoint> exactTypeMatchingCandindates = new List<FunctionEndPoint>();

            foreach (FunctionEndPoint possibleFep in functionEndPoint)
            {
                if (possibleFep.DoesTypeDeepMatch(formalParameters, runtimeCore))
                {
                    exactTypeMatchingCandindates.Add(possibleFep);
                }
            }


            //There was an exact match, so dispath to it
            if (exactTypeMatchingCandindates.Count > 0)
            {
                FunctionEndPoint fep = null;

                if (exactTypeMatchingCandindates.Count == 1)
                {
                    fep = exactTypeMatchingCandindates[0];
                }
                else
                {
                    fep = SelectFEPFromMultiple(stackFrame, runtimeCore,
                                                exactTypeMatchingCandindates, formalParameters);
                }

                return fep;
            }
            else
            {
                Dictionary<FunctionEndPoint, int> candidatesWithDistances = new Dictionary<FunctionEndPoint, int>();
                Dictionary<FunctionEndPoint, int> candidatesWithCastDistances = new Dictionary<FunctionEndPoint, int>();

                foreach (FunctionEndPoint fep in functionEndPoint)
                {
                    //@TODO(Luke): Is this value for allow array promotion correct?
                    int distance = fep.ComputeTypeDistance(formalParameters, runtimeCore.DSExecutable.classTable, runtimeCore, false);
                    if (distance !=
                        (int) ProcedureDistance.kInvalidDistance)
                        candidatesWithDistances.Add(fep, distance);
                }

                foreach (FunctionEndPoint fep in functionEndPoint)
                {
                    int dist = fep.ComputeCastDistance(formalParameters, runtimeCore.DSExecutable.classTable, runtimeCore);
                    candidatesWithCastDistances.Add(fep, dist);
                }

                List<FunctionEndPoint> candidateFunctions = GetCandidateFunctions(stackFrame, candidatesWithDistances);

                if (candidateFunctions.Count == 0)
                {
                    runtimeCore.RuntimeStatus.LogWarning(WarningID.kAmbiguousMethodDispatch,
                                                  Resources.kAmbigousMethodDispatch);
                    return null;
                }


                FunctionEndPoint compliantTarget = GetCompliantTarget(context, formalParameters, replicationControl,
                                                                      stackFrame, runtimeCore, candidatesWithCastDistances,
                                                                      candidateFunctions, candidatesWithDistances);

                return compliantTarget;
            }
        }
Beispiel #21
0
        /// <summary>
        /// Get complete match attempts to locate a function endpoint where 1 FEP matches all of the requirements for dispatch
        /// </summary>
        /// <param name="context"></param>
        /// <param name="arguments"></param>
        /// <param name="funcGroup"></param>
        /// <param name="replicationControl"></param>
        /// <param name="stackFrame"></param>
        /// <param name="core"></param>
        /// <param name="log"></param>
        /// <returns></returns>
        private FunctionEndPoint Case1GetCompleteMatchFEP(Context context, List<StackValue> arguments,
                                                          FunctionGroup funcGroup,
                                                          List<ReplicationInstruction> replicationInstructions, StackFrame stackFrame,
                                                          RuntimeCore runtimeCore, StringBuilder log)
        {
            //Exact match
            List<FunctionEndPoint> exactTypeMatchingCandindates =
                funcGroup.GetExactTypeMatches(context, arguments, replicationInstructions, stackFrame, runtimeCore);

            FunctionEndPoint fep = null;

            if (exactTypeMatchingCandindates.Count > 0)
            {
                if (exactTypeMatchingCandindates.Count == 1)
                {
                    //Exact match
                    fep = exactTypeMatchingCandindates[0];
                    log.AppendLine("1 exact match found - FEP selected" + fep);
                }
                else
                {
                    //Exact match with upcast
                    fep = SelectFEPFromMultiple(stackFrame,
                                                runtimeCore,
                                                exactTypeMatchingCandindates, arguments);

                    log.AppendLine(exactTypeMatchingCandindates.Count + "exact matches found - FEP selected" + fep);
                }
            }

            return fep;
        }
Beispiel #22
0
        //Inbound methods

        public StackValue JILDispatchViaNewInterpreter(
            Context context, 
            List<StackValue> arguments, 
            List<List<ReplicationGuide>> replicationGuides,
            List<AtLevel> atLevels,
            StackFrame stackFrame, RuntimeCore runtimeCore)
        {
#if DEBUG
            ArgumentSanityCheck(arguments);
#endif
            // Dispatch method
            context.IsImplicitCall = true;
            return DispatchNew(context, arguments, replicationGuides, atLevels, stackFrame, runtimeCore);
        }
Beispiel #23
0
        /// <summary>
        /// Reset an existing value and re-execute the vm
        /// </summary>
        /// <param name="varName"></param>
        /// <param name="value"></param>
        public void SetValueAndExecute(string varName, int? value)
        {
            core.Options.IsDeltaExecution = true;
            int nodesMarkedDirty = 0;
            bool wasSet = SetValue(varName, value, out nodesMarkedDirty);

            if (wasSet && nodesMarkedDirty > 0)
            {
                try
                {
                    foreach (ProtoCore.DSASM.CodeBlock codeblock in core.CodeBlockList)
                    {
                        ProtoCore.Runtime.Context context = new ProtoCore.Runtime.Context();

                        ProtoCore.DSASM.StackFrame stackFrame = new ProtoCore.DSASM.StackFrame(core.GlobOffset);
                        int locals = 0;

                        // Comment Jun: Tell the new bounce stackframe that this is an implicit bounce
                        // Register TX is used for this.
                        StackValue svCallConvention = StackUtils.BuildNode(AddressType.CallingConvention, (long)ProtoCore.DSASM.CallingConvention.BounceType.kImplicit);
                        stackFrame.SetAt(ProtoCore.DSASM.StackFrame.AbsoluteIndex.kRegisterTX, svCallConvention);

                        core.Bounce(codeblock.codeBlockId, codeblock.instrStream.entrypoint, context, stackFrame, locals, new ProtoCore.DebugServices.ConsoleEventSink());
                    }
                }
                catch
                {
                    throw;
                }
            }
        }
Beispiel #24
0
 public RuntimeCore(Options runtimeOptions, Executable executable, ProtoCore.Runtime.Context context)
 {
     this.context        = context;
     this.executable     = executable;
     this.runtimeOptions = runtimeOptions;
 }