Пример #1
0
        /// <summary>
        /// Retrieves an existing instance of a callsite associated with a UID
        /// It creates a new callsite if non was found
        /// </summary>
        /// <param name="core"></param>
        /// <param name="uid"></param>
        /// <returns></returns>
        public CallSite GetCallSite(GraphNode graphNode,
                                    int classScope,
                                    string methodName,
                                    Executable executable,
                                    int runningBlock,
                                    Options options,
                                    RuntimeStatus runtimeStatus
                                    )
        {
            Validity.Assert(null != executable.FunctionTable);
            CallSite csInstance = null;

            // TODO Jun: Currently generates a new callsite for imperative and
            // internally generated functions.
            // Fix the issues that cause the cache to go out of sync when
            // attempting to cache internal functions. This may require a
            // secondary callsite cache for internal functions so they dont
            // clash with the graphNode UID key
            var  language           = executable.instrStreamList[runningBlock].language;
            bool isImperative       = language == Language.kImperative;
            bool isInternalFunction = CoreUtils.IsInternalFunction(methodName);

            if (isInternalFunction || isImperative)
            {
                csInstance = new CallSite(classScope,
                                          methodName,
                                          executable.FunctionTable,
                                          options.ExecutionMode);
            }
            else if (!CallsiteCache.TryGetValue(graphNode.CallsiteIdentifier, out csInstance))
            {
                // Attempt to retrieve a preloaded callsite data (optional).
                var traceData = GetAndRemoveTraceDataForNode(graphNode.guid);

                csInstance = new CallSite(classScope,
                                          methodName,
                                          executable.FunctionTable,
                                          options.ExecutionMode,
                                          traceData);

                CallsiteCache[graphNode.CallsiteIdentifier] = csInstance;
                CallSiteToNodeMap[csInstance.CallSiteID]    = graphNode.guid;
                ASTToCallSiteMap[graphNode.AstID]           = csInstance;
            }

            if (graphNode != null && !CoreUtils.IsDisposeMethod(methodName))
            {
                csInstance.UpdateCallSite(classScope, methodName);
                if (options.IsDeltaExecution)
                {
                    runtimeStatus.ClearWarningForExpression(graphNode.exprUID);
                }
            }

            return(csInstance);
        }
Пример #2
0
        /// <summary>
        /// Retrieves an existing instance of a callsite associated with a UID
        /// It creates a new callsite if non was found
        /// </summary>
        /// <param name="core"></param>
        /// <param name="uid"></param>
        /// <returns></returns>
        public CallSite GetCallSite(int classScope, string methodName, Executable executable, RuntimeCore runtimeCore)
        {
            Validity.Assert(null != executable.FunctionTable);
            CallSite csInstance   = null;
            var      graphNode    = executable.ExecutingGraphnode;
            var      topGraphNode = graphNode;

            // If it is a nested function call, append all callsite ids
            List <string> callsiteIdentifiers = new List <string>();

            foreach (var prop in runtimeCore.InterpreterProps)
            {
                if (prop != null && prop.executingGraphNode != null && graphNode != prop.executingGraphNode)
                {
                    topGraphNode = prop.executingGraphNode;
                    if (!string.IsNullOrEmpty(topGraphNode.CallsiteIdentifier))
                    {
                        callsiteIdentifiers.Add(topGraphNode.CallsiteIdentifier);
                    }
                }
            }
            if (graphNode != null)
            {
                callsiteIdentifiers.Add(graphNode.CallsiteIdentifier);
            }
            var callsiteID = string.Join(";", callsiteIdentifiers.ToArray());

            // TODO Jun: Currently generates a new callsite for imperative and
            // internally generated functions.
            // Fix the issues that cause the cache to go out of sync when
            // attempting to cache internal functions. This may require a
            // secondary callsite cache for internal functions so they dont
            // clash with the graphNode UID key
            var  language           = executable.instrStreamList[runtimeCore.RunningBlock].language;
            bool isImperative       = language == Language.Imperative;
            bool isInternalFunction = CoreUtils.IsInternalFunction(methodName);

            if (isInternalFunction || isImperative)
            {
                csInstance = new CallSite(classScope,
                                          methodName,
                                          executable.FunctionTable,
                                          runtimeCore.Options.ExecutionMode);
            }
            else if (!CallsiteCache.TryGetValue(callsiteID, out csInstance))
            {
                // Attempt to retrieve a preloaded callsite data (optional).
                var traceData = GetAndRemoveTraceDataForNode(topGraphNode.guid, callsiteID);

                csInstance = new CallSite(classScope,
                                          methodName,
                                          executable.FunctionTable,
                                          runtimeCore.Options.ExecutionMode,
                                          traceData);

                CallsiteCache[callsiteID] = csInstance;
                CallSiteToNodeMap[csInstance.CallSiteID] = topGraphNode.guid;
            }

            if (graphNode != null && !CoreUtils.IsDisposeMethod(methodName))
            {
                csInstance.UpdateCallSite(classScope, methodName);
                if (runtimeCore.Options.IsDeltaExecution)
                {
                    runtimeCore.RuntimeStatus.ClearWarningForExpression(graphNode.exprUID);
                }
            }

            return(csInstance);
        }