internal FunctionInfo LookupFunctionInfo(DebugSourceSpan span) { foreach (var entry in _functionInfoMap) { if (entry.Key.Intersects(span)) { return entry.Value; } } return null; }
internal FunctionInfo LookupFunctionInfo(DebugSourceSpan span) { foreach (var entry in _functionInfoMap) { if (entry.Key.Intersects(span)) { return(entry.Value); } } return(null); }
internal int GetSequencePointIndex(FunctionInfo funcInfo) { DebugSourceSpan[] sequencePoints = funcInfo.SequencePoints; for (int i = 0; i < sequencePoints.Length; i++) { DebugSourceSpan sequencePoint = sequencePoints[i]; if (Intersects(sequencePoint)) { return(i); } } return(Int32.MaxValue); }
internal bool Intersects(DebugSourceSpan candidateSpan) { if (candidateSpan._sourceFile != _sourceFile) return false; if (candidateSpan._lineEnd < _lineStart || candidateSpan._lineStart > _lineEnd) return false; if (candidateSpan._lineStart == _lineEnd && candidateSpan._columnStart > _columnEnd) return false; if (candidateSpan._lineEnd == _lineStart && _columnStart > candidateSpan._columnEnd) return false; return true; }
internal bool Contains(DebugSourceSpan candidateSpan) { if (candidateSpan._sourceFile != _sourceFile) return false; if (candidateSpan._lineStart < _lineStart || candidateSpan._lineEnd > _lineEnd) return false; if (candidateSpan._lineStart == _lineStart && candidateSpan._columnStart < _columnStart) return false; if (candidateSpan._lineEnd == _lineEnd && candidateSpan._columnEnd > _columnEnd) return false; return true; }
internal FunctionInfo( Delegate generatorFactory, string name, DebugSourceSpan[] sequencePoints, IList<VariableInfo>[] scopedVariables, IList<VariableInfo> variables, object customPayload) { _generatorFactory = generatorFactory; _name = name; _sequencePoints = sequencePoints; _variableScopeMap = scopedVariables; _variables = variables; _customPayload = customPayload; _traceLocations = new bool[sequencePoints.Length]; }
void IDebugCallback.OnDebugEvent(TraceEventKind kind, DebugThread thread, FunctionInfo functionInfo, int sequencePointIndex, int stackDepth, object payload) { ITraceCallback traceCallback = _traceCallback; if (traceCallback != null) { // $TODO: what if the callback throws an exception? should we swallow it? var curThread = _traceFrame.Value; try { if (kind == TraceEventKind.FrameExit || kind == TraceEventKind.ThreadExit) { traceCallback.OnTraceEvent( kind, kind == TraceEventKind.FrameExit ? functionInfo.Name : null, null, SourceSpan.None, null, payload, functionInfo != null ? functionInfo.CustomPayload : null ); } else { DebugFrame leafFrame = thread.GetLeafFrame(); _traceFrame.Value = leafFrame; Debug.Assert(sequencePointIndex >= 0 && sequencePointIndex < functionInfo.SequencePoints.Length); DebugSourceSpan sourceSpan = functionInfo.SequencePoints[sequencePointIndex]; traceCallback.OnTraceEvent( kind, functionInfo.Name, sourceSpan.SourceFile.Name, sourceSpan.ToDlrSpan(), () => { return(leafFrame.GetLocalsScope()); }, payload, functionInfo.CustomPayload ); } } finally { _traceFrame.Value = curThread; } } }
private int GetSequencePointIndexForSourceSpan(string sourceFile, SourceSpan sourceSpan, DebugFrame frame) { DebugSourceFile debugSourceFile = _debugContext.Lookup(sourceFile); if (debugSourceFile == null) { return(Int32.MaxValue); } DebugSourceSpan debugSourceSpan = new DebugSourceSpan(debugSourceFile, sourceSpan); FunctionInfo leafFrameFuncInfo = frame.FunctionInfo; FunctionInfo funcInfo = debugSourceFile.LookupFunctionInfo(debugSourceSpan); // Verify that funcInfo matches the current frame if (funcInfo != leafFrameFuncInfo) { return(Int32.MaxValue); } // Get the target sequence point return(debugSourceSpan.GetSequencePointIndex(funcInfo)); }
internal bool Intersects(DebugSourceSpan candidateSpan) { if (candidateSpan._sourceFile != _sourceFile) { return(false); } if (candidateSpan._lineEnd < _lineStart || candidateSpan._lineStart > _lineEnd) { return(false); } if (candidateSpan._lineStart == _lineEnd && candidateSpan._columnStart > _columnEnd) { return(false); } if (candidateSpan._lineEnd == _lineStart && _columnStart > candidateSpan._columnEnd) { return(false); } return(true); }
internal bool Contains(DebugSourceSpan candidateSpan) { if (candidateSpan._sourceFile != _sourceFile) { return(false); } if (candidateSpan._lineStart < _lineStart || candidateSpan._lineEnd > _lineEnd) { return(false); } if (candidateSpan._lineStart == _lineStart && candidateSpan._columnStart < _columnStart) { return(false); } if (candidateSpan._lineEnd == _lineEnd && candidateSpan._columnEnd > _columnEnd) { return(false); } return(true); }
private int GetSequencePointIndexForSourceSpan(string sourceFile, SourceSpan sourceSpan, DebugFrame frame) { DebugSourceFile debugSourceFile = _debugContext.Lookup(sourceFile); if (debugSourceFile == null) { return Int32.MaxValue; } DebugSourceSpan debugSourceSpan = new DebugSourceSpan(debugSourceFile, sourceSpan); FunctionInfo leafFrameFuncInfo = frame.FunctionInfo; FunctionInfo funcInfo = debugSourceFile.LookupFunctionInfo(debugSourceSpan); // Verify that funcInfo matches the current frame if (funcInfo != leafFrameFuncInfo) { return Int32.MaxValue; } // Get the target sequence point return debugSourceSpan.GetSequencePointIndex(funcInfo); }
protected override MSAst.Expression VisitDebugInfo(MSAst.DebugInfoExpression node) { if (!node.IsClear) { MSAst.Expression transformedExpression; // Verify that DebugInfoExpression has valid SymbolDocumentInfo if (node.Document == null) { throw new InvalidOperationException( string.Format( CultureInfo.CurrentCulture, ErrorStrings.DebugInfoWithoutSymbolDocumentInfo, _locationCookie)); } DebugSourceFile sourceFile = _debugContext.GetDebugSourceFile( String.IsNullOrEmpty(node.Document.FileName) ? "<compile>" : node.Document.FileName); // Update the location cookie int locationCookie = _locationCookie++; if (!_transformToGenerator) { MSAst.Expression tracebackCall = null; if (locationCookie == 0) { tracebackCall = Ast.Empty(); } else { tracebackCall = Ast.Call( typeof(RuntimeOps).GetMethod(nameof(RuntimeOps.OnTraceEvent)), _thread, AstUtils.Constant(locationCookie), Ast.Convert(Ast.Constant(null), typeof(Exception)) ); } transformedExpression = Ast.Block( Ast.Assign( _debugMarker, AstUtils.Constant(locationCookie) ), Ast.IfThen( Ast.GreaterThan( Ast.Property(_sourceFilesToVariablesMap[sourceFile], "Mode"), Ast.Constant((int)DebugMode.ExceptionsOnly) ), Ast.IfThen( Ast.OrElse( Ast.Equal( Ast.Property(_sourceFilesToVariablesMap[sourceFile], "Mode"), Ast.Constant((int)DebugMode.FullyEnabled) ), Ast.ArrayIndex( _traceLocations, AstUtils.Constant(locationCookie) ) ), Ast.Block( _pushFrame ?? Ast.Empty(), tracebackCall ) ) ) ); } else { Debug.Assert(_generatorLabelTarget != null); transformedExpression = Ast.Block( AstUtils.YieldReturn( _generatorLabelTarget, _debugYieldValue, locationCookie ) ); // Update the variable scope map if (_currentLocals.Count > 0) { BlockExpression curentBlock = _currentLocals.Peek(); if (!_variableScopeMapCache.TryGetValue(curentBlock, out IList <VariableInfo> scopedVaribles)) { scopedVaribles = new List <VariableInfo>(); BlockExpression[] blocks = _currentLocals.ToArray(); for (int i = blocks.Length - 1; i >= 0; i--) { foreach (var variable in blocks[i].Variables) { scopedVaribles.Add(_localsToVarInfos[variable]); } } _variableScopeMapCache.Add(curentBlock, scopedVaribles); } _variableScopeMap.Add(locationCookie, scopedVaribles); } DebugSourceSpan span = new DebugSourceSpan( sourceFile, node.StartLine, node.StartColumn, node.EndLine, node.EndColumn); // Update the location-span map _markerLocationMap.Add(locationCookie, span); } return(transformedExpression); } return(Ast.Empty()); }