| File: CodeGen\MethodBody.cs | Web Access |
| Project: src\roslyn\src\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj (Microsoft.CodeAnalysis) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Collections.Immutable; using System.Diagnostics; using Microsoft.CodeAnalysis.Debugging; using Microsoft.CodeAnalysis.Emit; using Microsoft.CodeAnalysis.PooledObjects; namespace Microsoft.CodeAnalysis.CodeGen { /// <summary> /// Holds on to the method body data. /// </summary> internal sealed class MethodBody : Cci.IMethodBody { private readonly Cci.IMethodDefinition _parent; private readonly ImmutableArray<byte> _ilBits; private readonly ushort _maxStack; private readonly ImmutableArray<Cci.ILocalDefinition> _locals; private readonly ImmutableArray<Cci.ExceptionHandlerRegion> _exceptionHandlers; private readonly bool _areLocalsZeroed; // Debug information emitted to Release & Debug PDBs supporting the debugger, EEs and other tools: private readonly ImmutableArray<Cci.SequencePoint> _sequencePoints; private readonly ImmutableArray<Cci.LocalScope> _localScopes; private readonly Cci.IImportScope? _importScopeOpt; private readonly string? _stateMachineTypeNameOpt; private readonly ImmutableArray<StateMachineHoistedLocalScope> _stateMachineHoistedLocalScopes; private readonly bool _hasDynamicLocalVariables; private readonly StateMachineMoveNextBodyDebugInfo? _stateMachineMoveNextDebugInfoOpt; // Debug information emitted to Debug PDBs supporting EnC: private readonly DebugId _methodId; private readonly ImmutableArray<EncHoistedLocalInfo> _stateMachineHoistedLocalSlots; private readonly ImmutableArray<EncLambdaInfo> _lambdaDebugInfo; private readonly ImmutableArray<LambdaRuntimeRudeEditInfo> _orderedLambdaRuntimeRudeEdits; private readonly ImmutableArray<EncClosureInfo> _closureDebugInfo; private readonly StateMachineStatesDebugInfo _stateMachineStatesDebugInfo; // Data used when emitting EnC delta: private readonly ImmutableArray<Cci.ITypeReference?> _stateMachineAwaiterSlots; // Data used when emitting Dynamic Analysis resource generated by code coverage instrumentation. Empty if not applicable. private readonly ImmutableArray<SourceSpan> _codeCoverageSpans; private readonly bool _isPrimaryConstructor; public MethodBody( ImmutableArray<byte> ilBits, ushort maxStack, Cci.IMethodDefinition parent, DebugId methodId, ImmutableArray<Cci.ILocalDefinition> locals, SequencePointList? sequencePoints, DebugDocumentProvider? debugDocumentProvider, ImmutableArray<Cci.ExceptionHandlerRegion> exceptionHandlers, bool areLocalsZeroed, bool hasStackalloc, ImmutableArray<Cci.LocalScope> localScopes, bool hasDynamicLocalVariables, Cci.IImportScope? importScopeOpt, ImmutableArray<EncLambdaInfo> lambdaDebugInfo, ImmutableArray<LambdaRuntimeRudeEditInfo> orderedLambdaRuntimeRudeEdits, ImmutableArray<EncClosureInfo> closureDebugInfo, string? stateMachineTypeNameOpt, ImmutableArray<StateMachineHoistedLocalScope> stateMachineHoistedLocalScopes, ImmutableArray<EncHoistedLocalInfo> stateMachineHoistedLocalSlots, ImmutableArray<Cci.ITypeReference?> stateMachineAwaiterSlots, StateMachineStatesDebugInfo stateMachineStatesDebugInfo, StateMachineMoveNextBodyDebugInfo? stateMachineMoveNextDebugInfoOpt, ImmutableArray<SourceSpan> codeCoverageSpans, bool isPrimaryConstructor) { Debug.Assert(!locals.IsDefault); Debug.Assert(!exceptionHandlers.IsDefault); Debug.Assert(!localScopes.IsDefault); _ilBits = ilBits; _maxStack = maxStack; _parent = parent; _methodId = methodId; _locals = locals; _exceptionHandlers = exceptionHandlers; _areLocalsZeroed = areLocalsZeroed; HasStackalloc = hasStackalloc; _localScopes = localScopes; _hasDynamicLocalVariables = hasDynamicLocalVariables; _importScopeOpt = importScopeOpt; _lambdaDebugInfo = lambdaDebugInfo; _orderedLambdaRuntimeRudeEdits = orderedLambdaRuntimeRudeEdits; _closureDebugInfo = closureDebugInfo; _stateMachineTypeNameOpt = stateMachineTypeNameOpt; _stateMachineHoistedLocalScopes = stateMachineHoistedLocalScopes; _stateMachineHoistedLocalSlots = stateMachineHoistedLocalSlots; _stateMachineAwaiterSlots = stateMachineAwaiterSlots; _stateMachineStatesDebugInfo = stateMachineStatesDebugInfo; _stateMachineMoveNextDebugInfoOpt = stateMachineMoveNextDebugInfoOpt; _codeCoverageSpans = codeCoverageSpans; _sequencePoints = GetSequencePoints(sequencePoints, debugDocumentProvider); _isPrimaryConstructor = isPrimaryConstructor; } private static ImmutableArray<Cci.SequencePoint> GetSequencePoints(SequencePointList? sequencePoints, DebugDocumentProvider? debugDocumentProvider) { if (sequencePoints == null || sequencePoints.IsEmpty) { return ImmutableArray<Cci.SequencePoint>.Empty; } Debug.Assert(debugDocumentProvider != null); var sequencePointsBuilder = ArrayBuilder<Cci.SequencePoint>.GetInstance(); sequencePoints.GetSequencePoints(debugDocumentProvider, sequencePointsBuilder); return sequencePointsBuilder.ToImmutableAndFree(); } ImmutableArray<SourceSpan> Cci.IMethodBody.CodeCoverageSpans => _codeCoverageSpans; ImmutableArray<Cci.ExceptionHandlerRegion> Cci.IMethodBody.ExceptionRegions => _exceptionHandlers; bool Cci.IMethodBody.AreLocalsZeroed => _areLocalsZeroed; ImmutableArray<Cci.ILocalDefinition> Cci.IMethodBody.LocalVariables => _locals; Cci.IMethodDefinition Cci.IMethodBody.MethodDefinition => _parent; StateMachineMoveNextBodyDebugInfo? Cci.IMethodBody.MoveNextBodyInfo => _stateMachineMoveNextDebugInfoOpt; ushort Cci.IMethodBody.MaxStack => _maxStack; public ImmutableArray<byte> IL => _ilBits; public ImmutableArray<Cci.SequencePoint> SequencePoints => _sequencePoints; ImmutableArray<Cci.LocalScope> Cci.IMethodBody.LocalScopes => _localScopes; /// <summary> /// This is a list of the using directives that were in scope for this method body. /// </summary> Cci.IImportScope? Cci.IMethodBody.ImportScope => _importScopeOpt; string? Cci.IMethodBody.StateMachineTypeName => _stateMachineTypeNameOpt; ImmutableArray<StateMachineHoistedLocalScope> Cci.IMethodBody.StateMachineHoistedLocalScopes => _stateMachineHoistedLocalScopes; ImmutableArray<EncHoistedLocalInfo> Cci.IMethodBody.StateMachineHoistedLocalSlots => _stateMachineHoistedLocalSlots; ImmutableArray<Cci.ITypeReference?> Cci.IMethodBody.StateMachineAwaiterSlots => _stateMachineAwaiterSlots; bool Cci.IMethodBody.HasDynamicLocalVariables => _hasDynamicLocalVariables; public DebugId MethodId => _methodId; public ImmutableArray<EncLambdaInfo> LambdaDebugInfo => _lambdaDebugInfo; /// <summary> /// Ordered by <see cref="LambdaRuntimeRudeEditInfo.LambdaId"/>. /// </summary> public ImmutableArray<LambdaRuntimeRudeEditInfo> OrderedLambdaRuntimeRudeEdits => _orderedLambdaRuntimeRudeEdits; public ImmutableArray<EncClosureInfo> ClosureDebugInfo => _closureDebugInfo; public StateMachineStatesDebugInfo StateMachineStatesDebugInfo => _stateMachineStatesDebugInfo; /// <summary> /// True if there's a stackalloc somewhere in the method. /// </summary> public bool HasStackalloc { get; } public bool IsPrimaryConstructor => _isPrimaryConstructor; } }