Beispiel #1
0
        public void SetUpCallrForDebug(ProtoCore.Core core, ProtoCore.DSASM.Executive exec, ProcedureNode fNode, int pc, bool isBaseCall = false,
            ProtoCore.CallSite callsite = null, List<StackValue> arguments = null, List<List<ProtoCore.ReplicationGuide>> replicationGuides = null, ProtoCore.DSASM.StackFrame stackFrame = null,
            List<StackValue> dotCallDimensions = null, bool hasDebugInfo = false, bool isMember = false, StackValue? thisPtr = null)
        {
            //ProtoCore.DSASM.Executive exec = core.CurrentExecutive.CurrentDSASMExec;

            DebugFrame debugFrame = new DebugFrame();
            debugFrame.IsBaseCall = isBaseCall;
            debugFrame.Arguments = arguments;
            debugFrame.IsMemberFunction = isMember;
            debugFrame.ThisPtr = thisPtr;
            debugFrame.HasDebugInfo = hasDebugInfo;

            if (CoreUtils.IsDisposeMethod(fNode.name))
            {
                debugFrame.IsDisposeCall = true;
                ReturnPCFromDispose = DebugEntryPC;
            }

            if (RunMode == Runmode.StepNext)
            {
                debugFrame.FunctionStepOver = true;
            }

            bool isReplicating = false;
            bool isExternalFunction = false;
            
            // callsite is set to null for a base class constructor call in CALL
            if (callsite == null)
            {
                isReplicating = false;
                isExternalFunction = false;
                
                SetUpCallr(ref debugFrame, isReplicating, isExternalFunction, exec);
                DebugStackFrame.Push(debugFrame);

                return;
            }

            // Comment Jun: A dot call does not replicate and  must be handled immediately
            if (fNode.name == ProtoCore.DSASM.Constants.kDotMethodName)
            {
                isReplicating = false;
                isExternalFunction = false;
                debugFrame.IsDotCall = true;
                debugFrame.DotCallDimensions = dotCallDimensions;
                
                SetUpCallr(ref debugFrame, isReplicating, isExternalFunction, exec);
                DebugStackFrame.Push(debugFrame);

                return;
            }

            List<List<Lang.Replication.ReplicationInstruction>> replicationTrials;
            bool willReplicate = callsite.WillCallReplicate(new ProtoCore.Runtime.Context(), arguments, replicationGuides, stackFrame, core, out replicationTrials);
            
            // the inline conditional built-in is handled separately as 'WillCallReplicate' is always true in this case
            if(fNode.name.Equals(Constants.kInlineConditionalMethodName))
            {
                // The inline conditional built-in is created only for associative blocks and needs to be handled separately as below
                InstructionStream istream = core.DSExecutable.instrStreamList[CurrentBlockId];
                Validity.Assert(istream.language == Language.kAssociative);
                {
                    core.DebugProps.InlineConditionOptions.isInlineConditional = true;
                    core.DebugProps.InlineConditionOptions.startPc = pc;

                    core.DebugProps.InlineConditionOptions.endPc = FindEndPCForAssocGraphNode(pc, istream, fNode, exec.Properties.executingGraphNode, core.Options.ExecuteSSA);


                    core.DebugProps.InlineConditionOptions.instructionStream = core.RunningBlock;
                    debugFrame.IsInlineConditional = true;
                }
                
                // no replication case
                if (willReplicate && replicationTrials.Count == 1)
                {
                    core.DebugProps.InlineConditionOptions.ActiveBreakPoints.AddRange(core.Breakpoints);

                    /*if (core.DebugProps.RunMode == Runmode.StepNext)
                    {
                        core.Breakpoints.Clear();
                    }*/

                    isReplicating = false;
                    isExternalFunction = false;
                }
                else // an inline conditional call that replicates
                {
#if !__DEBUG_REPLICATE
                    // Clear all breakpoints for outermost replicated call
                    if(!DebugStackFrameContains(StackFrameFlagOptions.IsReplicating))
                    {
                        ActiveBreakPoints.AddRange(core.Breakpoints);
                        core.Breakpoints.Clear();
                    }
#endif
                    isExternalFunction = false;
                    isReplicating = true;
                }
                SetUpCallr(ref debugFrame, isReplicating, isExternalFunction, exec, 0);
                
                DebugStackFrame.Push(debugFrame);

                return;
            }            
            // Prevent breaking inside a function that is external except for dot calls
            // by clearing all breakpoints from outermost external function call
            // This check takes precedence over the replication check
            else if (fNode.isExternal && fNode.name != ProtoCore.DSASM.Constants.kDotMethodName)
            {
                // Clear all breakpoints 
                if (!DebugStackFrameContains(StackFrameFlagOptions.IsExternalFunction) && fNode.name != ProtoCore.DSASM.Constants.kFunctionRangeExpression)
                {
                    ActiveBreakPoints.AddRange(core.Breakpoints);
                    core.Breakpoints.Clear();
                }

                isExternalFunction = true;
                isReplicating = false;
            }
            // Find if function call will replicate or not and if so
            // prevent stepping in by removing all breakpoints from outermost replicated call
            else if (willReplicate)
            {
#if !__DEBUG_REPLICATE
                // Clear all breakpoints for outermost replicated call
                if(!DebugStackFrameContains(StackFrameFlagOptions.IsReplicating))
                {
                    ActiveBreakPoints.AddRange(core.Breakpoints);
                    core.Breakpoints.Clear();
                }
#endif

                isReplicating = true;
                isExternalFunction = false;
            }
            // For all other function calls
            else
            {
                isReplicating = false;
                isExternalFunction = false;
            }

            SetUpCallr(ref debugFrame, isReplicating, isExternalFunction, exec);
            DebugStackFrame.Push(debugFrame);
        }