using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using Microsoft.Cci; using Microsoft.CodeAnalysis.CSharp.Emit.NoPia; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CodeGen; using Microsoft.CodeAnalysis.Emit; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp; internal sealed class ClosureConversion : MethodToClassRewriter { internal sealed class Analysis : BoundTreeWalkerWithStackGuardWithoutRecursionOnTheLeftOfBinaryOperator { [DebuggerDisplay("{ToString(), nq}")] public sealed class Scope { public readonly Scope Parent; public readonly ArrayBuilder NestedScopes = ArrayBuilder.GetInstance(); public readonly ArrayBuilder NestedFunctions = ArrayBuilder.GetInstance(); public readonly SetWithInsertionOrder DeclaredVariables = new SetWithInsertionOrder(); public readonly BoundNode BoundNode; public readonly NestedFunction ContainingFunctionOpt; public ClosureEnvironment? DeclaredEnvironment; public bool CanMergeWithParent { get; internal set; } = true; public Scope(Scope parent, BoundNode boundNode, NestedFunction containingFunction) { Parent = parent; BoundNode = boundNode; ContainingFunctionOpt = containingFunction; } public void Free() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) Enumerator enumerator = NestedScopes.GetEnumerator(); while (enumerator.MoveNext()) { enumerator.Current.Free(); } NestedScopes.Free(); Enumerator enumerator2 = NestedFunctions.GetEnumerator(); while (enumerator2.MoveNext()) { enumerator2.Current.Free(); } NestedFunctions.Free(); } public override string ToString() { return ((object)BoundNode.Syntax.GetText((Encoding)null, (SourceHashAlgorithm)1)).ToString(); } } public sealed class NestedFunction { public readonly MethodSymbol OriginalMethodSymbol; public readonly SyntaxReference BlockSyntax; public readonly PooledHashSet CapturedVariables = PooledHashSet.GetInstance(); public readonly ArrayBuilder CapturedEnvironments = ArrayBuilder.GetInstance(); public ClosureEnvironment ContainingEnvironmentOpt; private bool _capturesThis; public SynthesizedClosureMethod SynthesizedLoweredMethod; public bool CapturesThis { get { return _capturesThis; } set { _capturesThis = value; } } public NestedFunction(MethodSymbol symbol, SyntaxReference blockSyntax) { OriginalMethodSymbol = symbol; BlockSyntax = blockSyntax; } public void Free() { CapturedVariables.Free(); CapturedEnvironments.Free(); } } public sealed class ClosureEnvironment { public readonly SetWithInsertionOrder CapturedVariables; public bool CapturesParent; public readonly bool IsStruct; internal SynthesizedClosureEnvironment SynthesizedEnvironment; public ClosureEnvironment(IEnumerable capturedVariables, bool isStruct) { CapturedVariables = new SetWithInsertionOrder(); foreach (Symbol capturedVariable in capturedVariables) { CapturedVariables.Add(capturedVariable); } IsStruct = isStruct; } } private class ScopeTreeBuilder : BoundTreeWalkerWithStackGuardWithoutRecursionOnTheLeftOfBinaryOperator { private Scope _currentScope; private NestedFunction _currentFunction; private bool _inExpressionTree; private readonly SmallDictionary _localToScope = new SmallDictionary(); private readonly MethodSymbol _topLevelMethod; private readonly HashSet _methodsConvertedToDelegates; private readonly DiagnosticBag _diagnostics; private readonly PooledDictionary> _scopesAfterLabel = PooledDictionary>.GetInstance(); private readonly ArrayBuilder> _labelsInScope = ArrayBuilder>.GetInstance(); private ScopeTreeBuilder(Scope rootScope, MethodSymbol topLevelMethod, HashSet methodsConvertedToDelegates, DiagnosticBag diagnostics) { _currentScope = rootScope; ArrayBuilderExtensions.Push>(_labelsInScope, ArrayBuilder.GetInstance()); _topLevelMethod = topLevelMethod; _methodsConvertedToDelegates = methodsConvertedToDelegates; _diagnostics = diagnostics; } public static Scope Build(BoundNode node, MethodSymbol topLevelMethod, HashSet methodsConvertedToDelegates, DiagnosticBag diagnostics) { Scope scope = new Scope(null, node, null); new ScopeTreeBuilder(scope, topLevelMethod, methodsConvertedToDelegates, diagnostics).Build(); return scope; } private void Build() { DeclareLocals(_currentScope, _topLevelMethod.Parameters); if (_topLevelMethod.TryGetThisParameter(out var thisParameter) && (object)thisParameter != null) { DeclareLocals(_currentScope, ImmutableArray.Create((Symbol)thisParameter)); } Visit(_currentScope.BoundNode); foreach (ArrayBuilder value in ((Dictionary>)(object)_scopesAfterLabel).Values) { value.Free(); } _scopesAfterLabel.Free(); ArrayBuilderExtensions.Pop>(_labelsInScope).Free(); _labelsInScope.Free(); } public override BoundNode VisitMethodGroup(BoundMethodGroup node) { throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/ClosureConversion.Analysis.Tree.cs", 396); } public override BoundNode VisitBlock(BoundBlock node) { Scope currentScope = _currentScope; PushOrReuseScope(node, node.Locals); BoundNode? result = base.VisitBlock(node); PopScope(currentScope); return result; } public override BoundNode VisitCatchBlock(BoundCatchBlock node) { Scope currentScope = _currentScope; PushOrReuseScope(node, node.Locals); BoundNode? result = base.VisitCatchBlock(node); PopScope(currentScope); return result; } public override BoundNode VisitSequence(BoundSequence node) { Scope currentScope = _currentScope; PushOrReuseScope(node, node.Locals); BoundNode? result = base.VisitSequence(node); PopScope(currentScope); return result; } public override BoundNode VisitLambda(BoundLambda node) { bool inExpressionTree = _inExpressionTree; _inExpressionTree |= node.Type.IsExpressionTree(); _methodsConvertedToDelegates.Add(node.Symbol.OriginalDefinition); BoundNode? result = VisitNestedFunction(node.Symbol, node.Body); _inExpressionTree = inExpressionTree; return result; } public override BoundNode VisitLocalFunctionStatement(BoundLocalFunctionStatement node) { return VisitNestedFunction(node.Symbol.OriginalDefinition, node.Body); } protected override void VisitArguments(BoundCall node) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 if ((int)node.Method.MethodKind == 17) { AddIfCaptured(node.Method.OriginalDefinition, node.Syntax); } base.VisitArguments(node); } public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 MethodSymbol? methodOpt = node.MethodOpt; if ((object)methodOpt != null && (int)methodOpt.MethodKind == 17) { MethodSymbol originalDefinition = node.MethodOpt.OriginalDefinition; AddIfCaptured(originalDefinition, node.Syntax); _methodsConvertedToDelegates.Add(originalDefinition); } return base.VisitDelegateCreationExpression(node); } public override BoundNode VisitParameter(BoundParameter node) { AddIfCaptured(node.ParameterSymbol, node.Syntax); return base.VisitParameter(node); } public override BoundNode VisitLocal(BoundLocal node) { AddIfCaptured(node.LocalSymbol, node.Syntax); return base.VisitLocal(node); } public override BoundNode VisitBaseReference(BoundBaseReference node) { AddIfCaptured(_topLevelMethod.ThisParameter, node.Syntax); return base.VisitBaseReference(node); } public override BoundNode VisitThisReference(BoundThisReference node) { ParameterSymbol thisParameter = _topLevelMethod.ThisParameter; if (thisParameter != null) { AddIfCaptured(thisParameter, node.Syntax); } return base.VisitThisReference(node); } public override BoundNode VisitLabelStatement(BoundLabelStatement node) { ArrayBuilderExtensions.Peek>(_labelsInScope).Add(node.Label); ((Dictionary>)(object)_scopesAfterLabel).Add(node.Label, ArrayBuilder.GetInstance()); return base.VisitLabelStatement(node); } public override BoundNode VisitGotoStatement(BoundGotoStatement node) { CheckCanMergeWithParent(node.Label); return base.VisitGotoStatement(node); } public override BoundNode VisitConditionalGoto(BoundConditionalGoto node) { CheckCanMergeWithParent(node.Label); return base.VisitConditionalGoto(node); } private void CheckCanMergeWithParent(LabelSymbol jumpTarget) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (((Dictionary>)(object)_scopesAfterLabel).TryGetValue(jumpTarget, out ArrayBuilder value)) { Enumerator enumerator = value.GetEnumerator(); while (enumerator.MoveNext()) { enumerator.Current.CanMergeWithParent = false; } value.Clear(); } } private BoundNode? VisitNestedFunction(MethodSymbol functionSymbol, BoundBlock? body) { if (body == null) { _currentScope.NestedFunctions.Add(new NestedFunction(functionSymbol, null)); return null; } NestedFunction nestedFunction = new NestedFunction(functionSymbol, body.Syntax.GetReference()); _currentScope.NestedFunctions.Add(nestedFunction); NestedFunction currentFunction = _currentFunction; _currentFunction = nestedFunction; Scope currentScope = _currentScope; CreateAndPushScope(body); DeclareLocals(_currentScope, functionSymbol.Parameters, _inExpressionTree); BoundNode result = (_inExpressionTree ? base.VisitBlock(body) : VisitBlock(body)); PopScope(currentScope); _currentFunction = currentFunction; return result; } private void AddIfCaptured(Symbol symbol, SyntaxNode syntax) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Invalid comparison between Unknown and I4 if (_currentFunction == null || symbol is LocalSymbol { IsConst: not false } || (symbol is MethodSymbol methodSymbol && _currentFunction.OriginalMethodSymbol == methodSymbol) || !(symbol.ContainingSymbol != _currentFunction.OriginalMethodSymbol)) { return; } AddDiagnosticIfRestrictedType(symbol, syntax); Scope scope = _currentScope; NestedFunction nestedFunction = _currentFunction; while (nestedFunction != null && symbol.ContainingSymbol != nestedFunction.OriginalMethodSymbol) { ((HashSet)(object)nestedFunction.CapturedVariables).Add(symbol); while (scope.ContainingFunctionOpt == nestedFunction) { scope = scope.Parent; } nestedFunction = scope.ContainingFunctionOpt; } Scope scope2 = default(Scope); if ((int)symbol.Kind != 9 && _localToScope.TryGetValue(symbol, ref scope2)) { scope2.DeclaredVariables.Add(symbol); } } private void AddDiagnosticIfRestrictedType(Symbol capturedVariable, SyntaxNode syntax) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 SymbolKind kind = capturedVariable.Kind; TypeSymbol type; if ((int)kind != 8) { if ((int)kind != 13) { return; } type = ((ParameterSymbol)capturedVariable).Type; } else { type = ((LocalSymbol)capturedVariable).Type; } if (type.IsRestrictedType()) { _diagnostics.Add(ErrorCode.ERR_SpecialByRefInLambda, syntax.Location, type); } } private void PushOrReuseScope(BoundNode node, ImmutableArray locals) where TSymbol : Symbol { if (!locals.IsEmpty && _currentScope.BoundNode != node) { CreateAndPushScope(node); } DeclareLocals(_currentScope, locals); } private void CreateAndPushScope(BoundNode node) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) Scope scope = CreateNestedScope(_currentScope, _currentFunction); Enumerator enumerator = ArrayBuilderExtensions.Peek>(_labelsInScope).GetEnumerator(); while (enumerator.MoveNext()) { LabelSymbol current = enumerator.Current; ((Dictionary>)(object)_scopesAfterLabel)[current].Add(scope); } ArrayBuilderExtensions.Push>(_labelsInScope, ArrayBuilder.GetInstance()); _currentScope = scope; Scope CreateNestedScope(Scope parentScope, NestedFunction currentFunction) { Scope scope2 = new Scope(parentScope, node, currentFunction); parentScope.NestedScopes.Add(scope2); return scope2; } } private void PopScope(Scope scope) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (scope != _currentScope) { ArrayBuilder val = ArrayBuilderExtensions.Pop>(_labelsInScope); Enumerator enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { LabelSymbol current = enumerator.Current; ((Dictionary>)(object)_scopesAfterLabel)[current].Free(); ((Dictionary>)(object)_scopesAfterLabel).Remove(current); } val.Free(); _currentScope = _currentScope.Parent; } } private void DeclareLocals(Scope scope, ImmutableArray locals, bool declareAsFree = false) where TSymbol : Symbol { ImmutableArray.Enumerator enumerator = locals.GetEnumerator(); while (enumerator.MoveNext()) { TSymbol current = enumerator.Current; if (!declareAsFree) { _localToScope.Add((Symbol)current, scope); } } } } public readonly PooledHashSet MethodsConvertedToDelegates; public readonly Scope ScopeTree; private readonly MethodSymbol _topLevelMethod; private readonly int _topLevelMethodOrdinal; private readonly VariableSlotAllocator _slotAllocatorOpt; private readonly TypeCompilationState _compilationState; public bool CanTakeRefParameters(MethodSymbol function) { if (!function.IsAsync && !function.IsIterator) { return !((HashSet)(object)MethodsConvertedToDelegates).Contains(function); } return false; } private Analysis(Scope scopeTree, PooledHashSet methodsConvertedToDelegates, MethodSymbol topLevelMethod, int topLevelMethodOrdinal, VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState) { ScopeTree = scopeTree; MethodsConvertedToDelegates = methodsConvertedToDelegates; _topLevelMethod = topLevelMethod; _topLevelMethodOrdinal = topLevelMethodOrdinal; _slotAllocatorOpt = slotAllocatorOpt; _compilationState = compilationState; } public static Analysis Analyze(BoundNode node, MethodSymbol method, int topLevelMethodOrdinal, VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, DiagnosticBag diagnostics) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Invalid comparison between Unknown and I4 PooledHashSet instance = PooledHashSet.GetInstance(); Analysis analysis = new Analysis(ScopeTreeBuilder.Build(node, method, (HashSet)(object)instance, diagnostics), instance, method, topLevelMethodOrdinal, slotAllocatorOpt, compilationState); analysis.MakeAndAssignEnvironments(); analysis.ComputeLambdaScopesAndFrameCaptures(); if ((int)((CompilationOptions)compilationState.Compilation.Options).OptimizationLevel == 1) { analysis.MergeEnvironments(); } analysis.InlineThisOnlyEnvironments(); return analysis; } private static BoundNode FindNodeToAnalyze(BoundNode node) { while (true) { switch (node.Kind) { case BoundKind.SequencePoint: node = ((BoundSequencePoint)node).StatementOpt; break; case BoundKind.SequencePointWithSpan: node = ((BoundSequencePointWithSpan)node).StatementOpt; break; case BoundKind.FieldEqualsValue: case BoundKind.Block: case BoundKind.StatementList: return node; case BoundKind.GlobalStatementInitializer: return ((BoundGlobalStatementInitializer)node).Statement; default: throw ExceptionUtilities.UnexpectedValue((object)node.Kind); } } } private void ComputeLambdaScopesAndFrameCaptures() { VisitNestedFunctions(ScopeTree, delegate(Scope scope, NestedFunction function) { if (function.CapturedEnvironments.Count > 0) { PooledHashSet instance = PooledHashSet.GetInstance(); ISetExtensions.AddAll((ISet)instance, (IEnumerable)function.CapturedEnvironments); Scope scope2; for (scope2 = scope; scope2 != null; scope2 = scope2.Parent) { ClosureEnvironment declaredEnvironment = scope2.DeclaredEnvironment; if (declaredEnvironment != null && ((HashSet)(object)instance).Remove(declaredEnvironment) && !declaredEnvironment.IsStruct) { function.ContainingEnvironmentOpt = declaredEnvironment; break; } } ClosureEnvironment closureEnvironment = scope2?.DeclaredEnvironment; scope2 = scope2?.Parent; while (scope2 != null && ((HashSet)(object)instance).Count != 0) { ClosureEnvironment declaredEnvironment2 = scope2.DeclaredEnvironment; if (declaredEnvironment2 != null) { if (!declaredEnvironment2.IsStruct) { closureEnvironment.CapturesParent = true; closureEnvironment = declaredEnvironment2; } ((HashSet)(object)instance).Remove(declaredEnvironment2); } scope2 = scope2.Parent; } if (((HashSet)(object)instance).Count > 0) { throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/ClosureConversion.Analysis.cs", 188); } instance.Free(); } }); } private void InlineThisOnlyEnvironments() { if (!_topLevelMethod.TryGetThisParameter(out var thisParameter) || thisParameter == null) { return; } ClosureEnvironment env = ScopeTree.DeclaredEnvironment; if (env == null || env.CapturedVariables.Count > 1 || !env.CapturedVariables.Contains((Symbol)thisParameter)) { return; } if (env.IsStruct) { if (!CheckNestedFunctions(ScopeTree, (Scope scope, NestedFunction closure) => closure.CapturedEnvironments.Contains(env) && closure.ContainingEnvironmentOpt != null)) { RemoveEnv(); } } else { if ((object)VarianceSafety.GetEnclosingVariantInterface(_topLevelMethod) != null) { return; } RemoveEnv(); VisitNestedFunctions(ScopeTree, delegate(Scope scope, NestedFunction closure) { if (closure.ContainingEnvironmentOpt == env) { closure.ContainingEnvironmentOpt = null; } }); } void RemoveEnv() { ScopeTree.DeclaredEnvironment = null; VisitNestedFunctions(ScopeTree, delegate(Scope scope, NestedFunction nested) { int num = nested.CapturedEnvironments.IndexOf(env); if (num >= 0) { nested.CapturedEnvironments.RemoveAt(num); } }); } } private void MakeAndAssignEnvironments() { VisitScopeTree(ScopeTree, delegate(Scope scope) { SetWithInsertionOrder declaredVariables = scope.DeclaredVariables; if (declaredVariables.Count == 0) { return; } bool isStruct = (object)VarianceSafety.GetEnclosingVariantInterface(_topLevelMethod) == null; SetWithInsertionOrder closures = new SetWithInsertionOrder(); bool addedItem; do { addedItem = false; VisitNestedFunctions(scope, delegate(Scope closureScope, NestedFunction closure) { if (!closures.Contains(closure) && (((HashSet)(object)closure.CapturedVariables).Overlaps((IEnumerable)scope.DeclaredVariables) || ((HashSet)(object)closure.CapturedVariables).Overlaps((IEnumerable)((IEnumerable)closures).Select((NestedFunction c) => c.OriginalMethodSymbol)))) { closures.Add(closure); addedItem = true; isStruct &= CanTakeRefParameters(closure.OriginalMethodSymbol); } }); } while (addedItem); ClosureEnvironment closureEnvironment = new ClosureEnvironment((IEnumerable)declaredVariables, isStruct); scope.DeclaredEnvironment = closureEnvironment; _topLevelMethod.TryGetThisParameter(out var thisParameter); foreach (NestedFunction item in closures) { item.CapturedEnvironments.Add(closureEnvironment); if (thisParameter != null && closureEnvironment.CapturedVariables.Contains((Symbol)thisParameter)) { item.CapturesThis = true; } } }); } private PooledDictionary> CalculateFunctionsCapturingScopeVariables() { PooledDictionary> closuresCapturingScopeVariables = PooledDictionary>.GetInstance(); PooledDictionary environmentsToScopes = PooledDictionary.GetInstance(); VisitScopeTree(ScopeTree, delegate(Scope scope4) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (scope4.DeclaredEnvironment != null) { ((Dictionary>)(object)closuresCapturingScopeVariables)[scope4] = PooledHashSet.GetInstance(); ((Dictionary)(object)environmentsToScopes)[scope4.DeclaredEnvironment] = scope4; } Enumerator enumerator2 = scope4.NestedFunctions.GetEnumerator(); while (enumerator2.MoveNext()) { NestedFunction current = enumerator2.Current; Enumerator enumerator3 = current.CapturedEnvironments.GetEnumerator(); while (enumerator3.MoveNext()) { ClosureEnvironment current2 = enumerator3.Current; ((HashSet)(object)((Dictionary>)(object)closuresCapturingScopeVariables)[((Dictionary)(object)environmentsToScopes)[current2]]).Add(current); } } }); environmentsToScopes.Free(); Scope scope = default(Scope); PooledHashSet val = default(PooledHashSet); foreach (KeyValuePair> item in (Dictionary>)(object)closuresCapturingScopeVariables) { KeyValuePairUtil.Deconstruct>(item, ref scope, ref val); Scope scope2 = scope; PooledHashSet val2 = val; if (scope2.DeclaredEnvironment == null) { continue; } Scope scope3 = scope2; while (scope3.DeclaredEnvironment == null || scope3.DeclaredEnvironment.CapturesParent) { scope3 = scope3.Parent; if (scope3 == null) { throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/ClosureConversion.Analysis.cs", 402); } if (scope3.DeclaredEnvironment != null && !scope3.DeclaredEnvironment.IsStruct) { ISetExtensions.AddAll((ISet)((Dictionary>)(object)closuresCapturingScopeVariables)[scope3], (IEnumerable)val2); } } } return closuresCapturingScopeVariables; } private void MergeEnvironments() { PooledDictionary> val = CalculateFunctionsCapturingScopeVariables(); Scope scope = default(Scope); PooledHashSet val2 = default(PooledHashSet); foreach (KeyValuePair> item in (Dictionary>)(object)val) { KeyValuePairUtil.Deconstruct>(item, ref scope, ref val2); Scope scope2 = scope; PooledHashSet val3 = val2; if (((HashSet)(object)val3).Count == 0) { continue; } ClosureEnvironment declaredEnvironment = scope2.DeclaredEnvironment; if (declaredEnvironment.IsStruct) { continue; } Scope scope3 = scope2; Scope scope4 = scope2; while (scope4.Parent != null && scope4.CanMergeWithParent) { Scope parent = scope4.Parent; ClosureEnvironment declaredEnvironment2 = parent.DeclaredEnvironment; if (declaredEnvironment2 == null || declaredEnvironment2.IsStruct) { scope4 = parent; continue; } if (!((HashSet)(object)((Dictionary>)(object)val)[parent]).SetEquals((IEnumerable)val3)) { break; } scope3 = parent; scope4 = parent; } if (scope3 == scope2) { continue; } ClosureEnvironment declaredEnvironment3 = scope3.DeclaredEnvironment; foreach (Symbol capturedVariable in declaredEnvironment.CapturedVariables) { declaredEnvironment3.CapturedVariables.Add(capturedVariable); } scope2.DeclaredEnvironment = null; foreach (NestedFunction item2 in (HashSet)(object)val3) { item2.CapturedEnvironments.Remove(declaredEnvironment); if (!item2.CapturedEnvironments.Contains(declaredEnvironment3)) { item2.CapturedEnvironments.Add(declaredEnvironment3); } if (item2.ContainingEnvironmentOpt == declaredEnvironment) { item2.ContainingEnvironmentOpt = declaredEnvironment3; } } } foreach (PooledHashSet value in ((Dictionary>)(object)val).Values) { value.Free(); } val.Free(); } internal DebugId GetTopLevelMethodId() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) VariableSlotAllocator slotAllocatorOpt = _slotAllocatorOpt; return (DebugId)(((_003F?)((slotAllocatorOpt != null) ? slotAllocatorOpt.MethodId : ((DebugId?)null))) ?? new DebugId(_topLevelMethodOrdinal, ((CommonPEModuleBuilder)_compilationState.ModuleBuilderOpt).CurrentGenerationOrdinal)); } internal DebugId GetClosureId(SyntaxNode syntax, ArrayBuilder closureDebugInfo) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) DebugId val = default(DebugId); DebugId val2 = default(DebugId); if (_slotAllocatorOpt != null && _slotAllocatorOpt.TryGetPreviousClosure(syntax, ref val)) { val2 = val; } else { ((DebugId)(ref val2))._002Ector(closureDebugInfo.Count, ((CommonPEModuleBuilder)_compilationState.ModuleBuilderOpt).CurrentGenerationOrdinal); } int num = _topLevelMethod.CalculateLocalSyntaxOffset(LambdaUtilities.GetDeclaratorPosition(syntax), syntax.SyntaxTree); closureDebugInfo.Add(new ClosureDebugInfo(num, val2)); return val2; } public static Scope GetVariableDeclarationScope(Scope startingScope, Symbol variable) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Invalid comparison between Unknown and I4 //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 //IL_006d: Unknown result type (might be due to invalid IL or missing references) if (variable is ParameterSymbol { IsThis: not false }) { return null; } for (Scope scope = startingScope; scope != null; scope = scope.Parent) { SymbolKind kind = variable.Kind; if ((int)kind != 8) { if ((int)kind == 9) { Enumerator enumerator = scope.NestedFunctions.GetEnumerator(); while (enumerator.MoveNext()) { if (enumerator.Current.OriginalMethodSymbol == variable) { return scope; } } continue; } if ((int)kind != 13) { throw ExceptionUtilities.UnexpectedValue((object)variable.Kind); } } if (scope.DeclaredVariables.Contains(variable)) { return scope; } } return null; } public static Scope GetScopeParent(Scope treeRoot, BoundNode scopeNode) { return GetScopeWithMatchingBoundNode(treeRoot, scopeNode).Parent; } public static Scope GetScopeWithMatchingBoundNode(Scope treeRoot, BoundNode node) { return Helper(treeRoot) ?? throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/ClosureConversion.Analysis.cs", 601); Scope Helper(Scope currentScope) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (currentScope.BoundNode == node) { return currentScope; } Enumerator enumerator = currentScope.NestedScopes.GetEnumerator(); while (enumerator.MoveNext()) { Scope scope = Helper(enumerator.Current); if (scope != null) { return scope; } } return null; } } public static (NestedFunction, Scope) GetVisibleNestedFunction(Scope startingScope, MethodSymbol functionSymbol) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) for (Scope scope = startingScope; scope != null; scope = scope.Parent) { Enumerator enumerator = scope.NestedFunctions.GetEnumerator(); while (enumerator.MoveNext()) { NestedFunction current = enumerator.Current; if (current.OriginalMethodSymbol == functionSymbol) { return (current, scope); } } } throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/ClosureConversion.Analysis.cs", 643); } public static NestedFunction GetNestedFunctionInTree(Scope treeRoot, MethodSymbol functionSymbol) { return helper(treeRoot) ?? throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/ClosureConversion.Analysis.cs", 651); NestedFunction helper(Scope scope) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) Enumerator enumerator = scope.NestedFunctions.GetEnumerator(); while (enumerator.MoveNext()) { NestedFunction current = enumerator.Current; if (current.OriginalMethodSymbol == functionSymbol) { return current; } } Enumerator enumerator2 = scope.NestedScopes.GetEnumerator(); while (enumerator2.MoveNext()) { NestedFunction nestedFunction = helper(enumerator2.Current); if (nestedFunction != null) { return nestedFunction; } } return null; } } public void Free() { MethodsConvertedToDelegates.Free(); ScopeTree.Free(); } public static void VisitNestedFunctions(Scope scope, Action action) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) Enumerator enumerator = scope.NestedFunctions.GetEnumerator(); while (enumerator.MoveNext()) { NestedFunction current = enumerator.Current; action(scope, current); } Enumerator enumerator2 = scope.NestedScopes.GetEnumerator(); while (enumerator2.MoveNext()) { VisitNestedFunctions(enumerator2.Current, action); } } public static bool CheckNestedFunctions(Scope scope, Func func) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) Enumerator enumerator = scope.NestedFunctions.GetEnumerator(); while (enumerator.MoveNext()) { NestedFunction current = enumerator.Current; if (func(scope, current)) { return true; } } Enumerator enumerator2 = scope.NestedScopes.GetEnumerator(); while (enumerator2.MoveNext()) { if (CheckNestedFunctions(enumerator2.Current, func)) { return true; } } return false; } public static void VisitScopeTree(Scope treeRoot, Action action) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) action(treeRoot); Enumerator enumerator = treeRoot.NestedScopes.GetEnumerator(); while (enumerator.MoveNext()) { VisitScopeTree(enumerator.Current, action); } } } private readonly Analysis _analysis; private readonly MethodSymbol _topLevelMethod; private readonly MethodSymbol _substitutedSourceMethod; private readonly int _topLevelMethodOrdinal; private SynthesizedClosureEnvironment _lazyStaticLambdaFrame; private readonly Dictionary _parameterMap = new Dictionary(); private readonly Dictionary _frames = new Dictionary(); private readonly Dictionary _framePointers = new Dictionary(); private readonly HashSet _assignLocals; private MethodSymbol _currentMethod; private ParameterSymbol _currentFrameThis; private readonly ArrayBuilder _lambdaDebugInfoBuilder; private int _synthesizedFieldNameIdDispenser; private Symbol _innermostFramePointer; private TypeMap _currentLambdaBodyTypeMap; private ImmutableArray _currentTypeParameters; private BoundExpression _thisProxyInitDeferred; private bool _seenBaseCall; private bool _inExpressionLambda; private ArrayBuilder _addedLocals; private ArrayBuilder _addedStatements; private ArrayBuilder _synthesizedMethods; private readonly ImmutableHashSet _allCapturedVariables; protected override TypeMap TypeMap => _currentLambdaBodyTypeMap; protected override MethodSymbol CurrentMethod => _currentMethod; protected override NamedTypeSymbol ContainingType => _topLevelMethod.ContainingType; private ClosureConversion(Analysis analysis, NamedTypeSymbol thisType, ParameterSymbol thisParameterOpt, MethodSymbol method, int methodOrdinal, MethodSymbol substitutedSourceMethod, ArrayBuilder lambdaDebugInfoBuilder, VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, BindingDiagnosticBag diagnostics, HashSet assignLocals) : base(slotAllocatorOpt, compilationState, diagnostics) { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Invalid comparison between Unknown and I4 _topLevelMethod = method; _substitutedSourceMethod = substitutedSourceMethod; _topLevelMethodOrdinal = methodOrdinal; _lambdaDebugInfoBuilder = lambdaDebugInfoBuilder; _currentMethod = method; _analysis = analysis; _assignLocals = assignLocals; _currentTypeParameters = method.TypeParameters; _currentLambdaBodyTypeMap = TypeMap.Empty; _innermostFramePointer = (_currentFrameThis = thisParameterOpt); _framePointers[thisType] = thisParameterOpt; _seenBaseCall = (int)method.MethodKind != 1; _synthesizedFieldNameIdDispenser = 1; ImmutableHashSet.Builder allCapturedVars = ImmutableHashSet.CreateBuilder(); Analysis.VisitNestedFunctions(analysis.ScopeTree, delegate(Analysis.Scope scope, Analysis.NestedFunction function) { allCapturedVars.UnionWith((IEnumerable)function.CapturedVariables); }); _allCapturedVariables = allCapturedVars.ToImmutable(); } protected override bool NeedsProxy(Symbol localOrParameter) { return _allCapturedVariables.Contains(localOrParameter); } public static BoundStatement Rewrite(BoundStatement loweredBody, NamedTypeSymbol thisType, ParameterSymbol thisParameter, MethodSymbol method, int methodOrdinal, MethodSymbol substitutedSourceMethod, ArrayBuilder lambdaDebugInfoBuilder, ArrayBuilder closureDebugInfoBuilder, VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, BindingDiagnosticBag diagnostics, HashSet assignLocals) { Analysis analysis = Analysis.Analyze(loweredBody, method, methodOrdinal, slotAllocatorOpt, compilationState, ((BindingDiagnosticBag)diagnostics).DiagnosticBag); ClosureConversion closureConversion = new ClosureConversion(analysis, thisType, thisParameter, method, methodOrdinal, substitutedSourceMethod, lambdaDebugInfoBuilder, slotAllocatorOpt, compilationState, diagnostics, assignLocals); closureConversion.SynthesizeClosureEnvironments(closureDebugInfoBuilder); closureConversion.SynthesizeClosureMethods(); BoundStatement result = closureConversion.AddStatementsIfNeeded((BoundStatement)closureConversion.Visit(loweredBody)); if (closureConversion._synthesizedMethods != null) { if (compilationState.SynthesizedMethods == null) { compilationState.SynthesizedMethods = closureConversion._synthesizedMethods; } else { compilationState.SynthesizedMethods.AddRange(closureConversion._synthesizedMethods); closureConversion._synthesizedMethods.Free(); } } analysis.Free(); return result; } private BoundStatement AddStatementsIfNeeded(BoundStatement body) { if (_addedLocals != null) { _addedStatements.Add(body); body = new BoundBlock(body.Syntax, _addedLocals.ToImmutableAndFree(), _addedStatements.ToImmutableAndFree()) { WasCompilerGenerated = true }; _addedLocals = null; _addedStatements = null; } return body; } private void SynthesizeClosureEnvironments(ArrayBuilder closureDebugInfo) { Analysis.VisitScopeTree(_analysis.ScopeTree, delegate(Analysis.Scope scope) { Analysis.ClosureEnvironment declaredEnvironment = scope.DeclaredEnvironment; if (declaredEnvironment != null) { SynthesizedClosureEnvironment synthesizedClosureEnvironment = (declaredEnvironment.SynthesizedEnvironment = MakeFrame(scope, declaredEnvironment)); ((PEModuleBuilder)CompilationState.ModuleBuilderOpt).AddSynthesizedDefinition(ContainingType, (INestedTypeDefinition)(object)synthesizedClosureEnvironment.GetCciAdapter()); if (synthesizedClosureEnvironment.Constructor != null) { AddSynthesizedMethod(synthesizedClosureEnvironment.Constructor, FlowAnalysisPass.AppendImplicitReturn(MethodCompiler.BindSynthesizedMethodBody(synthesizedClosureEnvironment.Constructor, CompilationState, Diagnostics), synthesizedClosureEnvironment.Constructor)); } _frames.Add(scope.BoundNode, declaredEnvironment); } }); SynthesizedClosureEnvironment MakeFrame(Analysis.Scope scope, Analysis.ClosureEnvironment env) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) SyntaxNode syntax = scope.BoundNode.Syntax; DebugId topLevelMethodId = _analysis.GetTopLevelMethodId(); DebugId closureId = _analysis.GetClosureId(syntax, closureDebugInfo); MethodSymbol methodSymbol = scope.ContainingFunctionOpt?.OriginalMethodSymbol ?? _topLevelMethod; if ((object)_substitutedSourceMethod != null && methodSymbol == _topLevelMethod) { methodSymbol = _substitutedSourceMethod; } SynthesizedClosureEnvironment synthesizedClosureEnvironment = new SynthesizedClosureEnvironment(_topLevelMethod, methodSymbol, env.IsStruct, syntax, topLevelMethodId, closureId); foreach (Symbol capturedVariable in env.CapturedVariables) { LambdaCapturedVariable lambdaCapturedVariable = LambdaCapturedVariable.Create(synthesizedClosureEnvironment, capturedVariable, ref _synthesizedFieldNameIdDispenser); proxies.Add(capturedVariable, new CapturedToFrameSymbolReplacement(lambdaCapturedVariable, isReusable: false)); synthesizedClosureEnvironment.AddHoistedField(lambdaCapturedVariable); ((PEModuleBuilder)CompilationState.ModuleBuilderOpt).AddSynthesizedDefinition((NamedTypeSymbol)synthesizedClosureEnvironment, (IFieldDefinition)(object)lambdaCapturedVariable.GetCciAdapter()); } return synthesizedClosureEnvironment; } } private void SynthesizeClosureMethods() { Analysis.VisitNestedFunctions(_analysis.ScopeTree, delegate(Analysis.Scope scope, Analysis.NestedFunction nestedFunction) { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) MethodSymbol originalMethodSymbol = nestedFunction.OriginalMethodSymbol; SyntaxNode syntax = originalMethodSymbol.DeclaringSyntaxReferences[0].GetSyntax(default(CancellationToken)); ClosureKind closureKind; NamedTypeSymbol containingType; int closureOrdinal; if (nestedFunction.ContainingEnvironmentOpt != null) { SynthesizedClosureEnvironment synthesizedEnvironment = nestedFunction.ContainingEnvironmentOpt.SynthesizedEnvironment; closureKind = ClosureKind.General; containingType = synthesizedEnvironment; closureOrdinal = synthesizedEnvironment.ClosureOrdinal; } else if (nestedFunction.CapturesThis) { containingType = _topLevelMethod.ContainingType; closureKind = ClosureKind.ThisOnly; closureOrdinal = -2; } else if ((nestedFunction.CapturedEnvironments.Count == 0 && (int)originalMethodSymbol.MethodKind == 0 && ((HashSet)(object)_analysis.MethodsConvertedToDelegates).Contains(originalMethodSymbol)) || (object)VarianceSafety.GetEnclosingVariantInterface(_topLevelMethod) != null) { containingType = GetStaticFrame(Diagnostics, syntax); closureKind = ClosureKind.Singleton; closureOrdinal = -1; } else { containingType = _topLevelMethod.ContainingType; closureKind = ClosureKind.Static; closureOrdinal = -1; } DebugId topLevelMethodId = _analysis.GetTopLevelMethodId(); DebugId lambdaId = GetLambdaId(syntax, closureKind, closureOrdinal); SynthesizedClosureMethod synthesizedLoweredMethod = new SynthesizedClosureMethod(containingType, getStructEnvironments(nestedFunction), closureKind, _topLevelMethod, topLevelMethodId, originalMethodSymbol, nestedFunction.BlockSyntax, lambdaId, CompilationState); nestedFunction.SynthesizedLoweredMethod = synthesizedLoweredMethod; }); static ImmutableArray getStructEnvironments(Analysis.NestedFunction function) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) ArrayBuilder instance = ArrayBuilder.GetInstance(); Enumerator enumerator = function.CapturedEnvironments.GetEnumerator(); while (enumerator.MoveNext()) { Analysis.ClosureEnvironment current = enumerator.Current; if (current.IsStruct) { instance.Add(current.SynthesizedEnvironment); } } return instance.ToImmutableAndFree(); } } private SynthesizedClosureEnvironment GetStaticFrame(BindingDiagnosticBag diagnostics, SyntaxNode syntax) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) if ((object)_lazyStaticLambdaFrame == null) { bool flag = !_topLevelMethod.IsGenericMethod; if (flag) { _lazyStaticLambdaFrame = CompilationState.StaticLambdaFrame; } if ((object)_lazyStaticLambdaFrame == null) { DebugId topLevelMethodId = default(DebugId); if (flag) { ((DebugId)(ref topLevelMethodId))._002Ector(-1, ((CommonPEModuleBuilder)CompilationState.ModuleBuilderOpt).CurrentGenerationOrdinal); } else { topLevelMethodId = _analysis.GetTopLevelMethodId(); } DebugId closureId = default(DebugId); MethodSymbol containingMethod = (flag ? null : (_substitutedSourceMethod ?? _topLevelMethod)); _lazyStaticLambdaFrame = new SynthesizedClosureEnvironment(_topLevelMethod, containingMethod, isStruct: false, null, topLevelMethodId, closureId); if (flag) { CompilationState.StaticLambdaFrame = _lazyStaticLambdaFrame; } SynthesizedClosureEnvironment lazyStaticLambdaFrame = _lazyStaticLambdaFrame; ((PEModuleBuilder)CompilationState.ModuleBuilderOpt).AddSynthesizedDefinition(ContainingType, (INestedTypeDefinition)(object)lazyStaticLambdaFrame.GetCciAdapter()); AddSynthesizedMethod(lazyStaticLambdaFrame.Constructor, FlowAnalysisPass.AppendImplicitReturn(MethodCompiler.BindSynthesizedMethodBody(lazyStaticLambdaFrame.Constructor, CompilationState, diagnostics), lazyStaticLambdaFrame.Constructor)); SyntheticBoundNodeFactory syntheticBoundNodeFactory = new SyntheticBoundNodeFactory(lazyStaticLambdaFrame.StaticConstructor, syntax, CompilationState, diagnostics); BoundBlock body = syntheticBoundNodeFactory.Block(syntheticBoundNodeFactory.Assignment(syntheticBoundNodeFactory.Field(null, lazyStaticLambdaFrame.SingletonCache), syntheticBoundNodeFactory.New(lazyStaticLambdaFrame.Constructor)), new BoundReturnStatement(syntax, (RefKind)0, null, @checked: false)); AddSynthesizedMethod(lazyStaticLambdaFrame.StaticConstructor, body); } } return _lazyStaticLambdaFrame; } private BoundExpression FrameOfType(SyntaxNode syntax, NamedTypeSymbol frameType) { return FramePointer(syntax, frameType.OriginalDefinition); } protected override BoundExpression FramePointer(SyntaxNode syntax, NamedTypeSymbol frameClass) { if ((object)_currentFrameThis != null && TypeSymbol.Equals(_currentFrameThis.Type, frameClass, (TypeCompareKind)0)) { return new BoundThisReference(syntax, frameClass); } SynthesizedClosureMethod synthesizedClosureMethod = _currentMethod as SynthesizedClosureMethod; if (synthesizedClosureMethod != null) { for (int i = synthesizedClosureMethod.ParameterCount - synthesizedClosureMethod.ExtraSynthesizedParameterCount; i < synthesizedClosureMethod.ParameterCount; i++) { ParameterSymbol parameterSymbol = synthesizedClosureMethod.Parameters[i]; if (TypeSymbol.Equals(parameterSymbol.Type.OriginalDefinition, frameClass, (TypeCompareKind)0)) { return new BoundParameter(syntax, parameterSymbol); } } } Symbol symbol = _framePointers[frameClass]; if (proxies.TryGetValue(symbol, out CapturedSymbolReplacement value)) { return value.Replacement(syntax, (NamedTypeSymbol frameType) => FramePointer(syntax, frameType)); } LocalSymbol localSymbol = (LocalSymbol)symbol; return new BoundLocal(syntax, localSymbol, null, localSymbol.Type); } private static void InsertAndFreePrologue(ArrayBuilder result, ArrayBuilder prologue) where T : BoundNode { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) Enumerator enumerator = prologue.GetEnumerator(); while (enumerator.MoveNext()) { T current = enumerator.Current; if (current is BoundStatement boundStatement) { result.Add(boundStatement); } else { result.Add((BoundStatement)new BoundExpressionStatement(current.Syntax, (BoundExpression)(object)current)); } } prologue.Free(); } private BoundNode IntroduceFrame(BoundNode node, Analysis.ClosureEnvironment env, Func, ArrayBuilder, BoundNode> F) { SynthesizedClosureEnvironment synthesizedEnvironment = env.SynthesizedEnvironment; ImmutableArray typeArguments = ImmutableArray.Create(ImmutableArrayExtensions.SelectAsArray(_currentTypeParameters, (Func)((TypeParameterSymbol t) => TypeWithAnnotations.Create(t))), 0, synthesizedEnvironment.Arity); NamedTypeSymbol namedTypeSymbol = synthesizedEnvironment.ConstructIfGeneric(typeArguments); LocalSymbol localSymbol = new SynthesizedLocal(_topLevelMethod, TypeWithAnnotations.Create(namedTypeSymbol), (SynthesizedLocalKind)30, synthesizedEnvironment.ScopeSyntaxOpt, isPinned: false, isKnownToReferToTempIfReferenceType: false, (RefKind)0); SyntaxNode syntax = node.Syntax; ArrayBuilder instance = ArrayBuilder.GetInstance(); if ((object)synthesizedEnvironment.Constructor != null) { MethodSymbol constructor = synthesizedEnvironment.Constructor.AsMember(namedTypeSymbol); instance.Add((BoundExpression)new BoundAssignmentOperator(syntax, new BoundLocal(syntax, localSymbol, null, namedTypeSymbol), new BoundObjectCreationExpression(syntax, constructor), namedTypeSymbol)); } CapturedSymbolReplacement value = null; if ((object)_innermostFramePointer != null) { proxies.TryGetValue(_innermostFramePointer, out value); if (env.CapturesParent) { LambdaCapturedVariable lambdaCapturedVariable = LambdaCapturedVariable.Create(synthesizedEnvironment, _innermostFramePointer, ref _synthesizedFieldNameIdDispenser); FieldSymbol fieldSymbol = lambdaCapturedVariable.AsMember(namedTypeSymbol); BoundExpression boundExpression = new BoundFieldAccess(syntax, new BoundLocal(syntax, localSymbol, null, namedTypeSymbol), fieldSymbol, null); BoundExpression right = FrameOfType(syntax, fieldSymbol.Type as NamedTypeSymbol); BoundExpression boundExpression2 = new BoundAssignmentOperator(syntax, boundExpression, right, boundExpression.Type); instance.Add(boundExpression2); if (CompilationState.Emitting) { synthesizedEnvironment.AddHoistedField(lambdaCapturedVariable); ((PEModuleBuilder)CompilationState.ModuleBuilderOpt).AddSynthesizedDefinition((NamedTypeSymbol)synthesizedEnvironment, (IFieldDefinition)(object)lambdaCapturedVariable.GetCciAdapter()); } proxies[_innermostFramePointer] = new CapturedToFrameSymbolReplacement(lambdaCapturedVariable, isReusable: false); } } foreach (Symbol capturedVariable in env.CapturedVariables) { InitVariableProxy(syntax, capturedVariable, localSymbol, instance); } Symbol innermostFramePointer = _innermostFramePointer; if (!localSymbol.Type.IsValueType) { _innermostFramePointer = localSymbol; } ArrayBuilder instance2 = ArrayBuilder.GetInstance(); instance2.Add(localSymbol); _framePointers.Add(synthesizedEnvironment, localSymbol); BoundNode result = F(instance, instance2); _innermostFramePointer = innermostFramePointer; if ((object)_innermostFramePointer != null) { if (value != null) { proxies[_innermostFramePointer] = value; return result; } proxies.Remove(_innermostFramePointer); } return result; } private void InitVariableProxy(SyntaxNode syntax, Symbol symbol, LocalSymbol framePointer, ArrayBuilder prologue) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Invalid comparison between Unknown and I4 if (!proxies.TryGetValue(symbol, out CapturedSymbolReplacement value)) { return; } SymbolKind kind = symbol.Kind; BoundExpression boundExpression; if ((int)kind != 8) { if ((int)kind != 13) { throw ExceptionUtilities.UnexpectedValue((object)symbol.Kind); } ParameterSymbol parameterSymbol = (ParameterSymbol)symbol; if (!_parameterMap.TryGetValue(parameterSymbol, out var value2)) { value2 = parameterSymbol; } boundExpression = new BoundParameter(syntax, value2); } else { LocalSymbol localSymbol = (LocalSymbol)symbol; if (_assignLocals == null || !_assignLocals.Contains(localSymbol)) { return; } if (!localMap.TryGetValue(localSymbol, out LocalSymbol value3)) { value3 = localSymbol; } boundExpression = new BoundLocal(syntax, value3, null, value3.Type); } BoundExpression left = value.Replacement(syntax, (NamedTypeSymbol frameType1) => new BoundLocal(syntax, framePointer, null, framePointer.Type)); BoundAssignmentOperator boundAssignmentOperator = new BoundAssignmentOperator(syntax, left, boundExpression, boundExpression.Type); if ((int)_currentMethod.MethodKind == 1 && symbol == _currentMethod.ThisParameter && !_seenBaseCall && !(_currentMethod is SynthesizedPrimaryConstructor)) { _thisProxyInitDeferred = boundAssignmentOperator; } else { prologue.Add((BoundExpression)boundAssignmentOperator); } } protected override BoundNode VisitUnhoistedParameter(BoundParameter node) { if (_parameterMap.TryGetValue(node.ParameterSymbol, out var value)) { return new BoundParameter(node.Syntax, value, node.HasErrors); } return base.VisitUnhoistedParameter(node); } public override BoundNode VisitThisReference(BoundThisReference node) { if (!(_currentMethod == _topLevelMethod) && !(_topLevelMethod.ThisParameter == null)) { return FramePointer(node.Syntax, (NamedTypeSymbol)node.Type); } return node; } public override BoundNode VisitBaseReference(BoundBaseReference node) { if (_currentMethod.IsStatic || !TypeSymbol.Equals(_currentMethod.ContainingType, _topLevelMethod.ContainingType, (TypeCompareKind)0)) { return FramePointer(node.Syntax, _topLevelMethod.ContainingType); } return node; } public override BoundNode VisitMethodDefIndex(BoundMethodDefIndex node) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 TypeSymbol type = VisitType(node.Type); MethodKind methodKind = node.Method.MethodKind; bool flag = (((int)methodKind == 0 || (int)methodKind == 17) ? true : false); MethodSymbol method = (flag ? Analysis.GetNestedFunctionInTree(_analysis.ScopeTree, node.Method.OriginalDefinition).SynthesizedLoweredMethod : node.Method); return node.Update(method, type); } private void RemapLocalFunction(SyntaxNode syntax, MethodSymbol localFunc, out BoundExpression receiver, out MethodSymbol method, ref ImmutableArray arguments, ref ImmutableArray argRefKinds) { SynthesizedClosureMethod synthesizedLoweredMethod = Analysis.GetNestedFunctionInTree(_analysis.ScopeTree, localFunc.OriginalDefinition).SynthesizedLoweredMethod; int extraSynthesizedParameterCount = synthesizedLoweredMethod.ExtraSynthesizedParameterCount; if (extraSynthesizedParameterCount != 0) { ArrayBuilder instance = ArrayBuilder.GetInstance(synthesizedLoweredMethod.ParameterCount); instance.AddRange(arguments); for (int i = synthesizedLoweredMethod.ParameterCount - extraSynthesizedParameterCount; i < synthesizedLoweredMethod.ParameterCount; i++) { NamedTypeSymbol namedTypeSymbol = (NamedTypeSymbol)synthesizedLoweredMethod.Parameters[i].Type.OriginalDefinition; if (namedTypeSymbol.Arity > 0) { ImmutableArray constructedFromTypeParameters = ((SynthesizedClosureEnvironment)namedTypeSymbol).ConstructedFromTypeParameters; ImmutableArray immutableArray = TypeMap.SubstituteTypeParameters(constructedFromTypeParameters); namedTypeSymbol = namedTypeSymbol.Construct(immutableArray); } BoundExpression boundExpression = FrameOfType(syntax, namedTypeSymbol); instance.Add(boundExpression); } ArrayBuilder instance2 = ArrayBuilder.GetInstance(instance.Count); if (!argRefKinds.IsDefault) { instance2.AddRange(argRefKinds); } else { instance2.AddMany((RefKind)0, arguments.Length); } instance2.AddMany((RefKind)1, extraSynthesizedParameterCount); arguments = instance.ToImmutableAndFree(); argRefKinds = instance2.ToImmutableAndFree(); } method = synthesizedLoweredMethod; RemapLambdaOrLocalFunction(syntax, localFunc, SubstituteTypeArguments(localFunc.TypeArgumentsWithAnnotations), synthesizedLoweredMethod.ClosureKind, ref method, out receiver, out var _); } private ImmutableArray SubstituteTypeArguments(ImmutableArray typeArguments) { if (typeArguments.IsEmpty) { return typeArguments; } ArrayBuilder instance = ArrayBuilder.GetInstance(typeArguments.Length); ImmutableArray.Enumerator enumerator = typeArguments.GetEnumerator(); while (enumerator.MoveNext()) { TypeWithAnnotations typeWithAnnotations = enumerator.Current; TypeWithAnnotations previous; do { previous = typeWithAnnotations; typeWithAnnotations = TypeMap.SubstituteType(previous); } while (!TypeSymbol.Equals(previous.Type, typeWithAnnotations.Type, (TypeCompareKind)0)); instance.Add(typeWithAnnotations); } return instance.ToImmutableAndFree(); } private void RemapLambdaOrLocalFunction(SyntaxNode syntax, MethodSymbol originalMethod, ImmutableArray typeArgumentsOpt, ClosureKind closureKind, ref MethodSymbol synthesizedMethod, out BoundExpression receiver, out NamedTypeSymbol constructedFrame) { NamedTypeSymbol containingType = synthesizedMethod.ContainingType; SynthesizedClosureEnvironment synthesizedClosureEnvironment = containingType as SynthesizedClosureEnvironment; int num = (synthesizedClosureEnvironment?.Arity ?? 0) + synthesizedMethod.Arity; ImmutableArray immutableArray = ImmutableArray.Create(ImmutableArrayExtensions.SelectAsArray(_currentTypeParameters, (Func)((TypeParameterSymbol t) => TypeWithAnnotations.Create(t))), 0, num - originalMethod.Arity); if (!typeArgumentsOpt.IsDefault) { immutableArray = ImmutableArrayExtensions.Concat(immutableArray, typeArgumentsOpt); } if ((object)synthesizedClosureEnvironment != null && synthesizedClosureEnvironment.Arity != 0) { ImmutableArray typeArguments = ImmutableArray.Create(immutableArray, 0, synthesizedClosureEnvironment.Arity); immutableArray = ImmutableArray.Create(immutableArray, synthesizedClosureEnvironment.Arity, immutableArray.Length - synthesizedClosureEnvironment.Arity); constructedFrame = synthesizedClosureEnvironment.Construct(typeArguments); } else { constructedFrame = containingType; } synthesizedMethod = synthesizedMethod.AsMember(constructedFrame); if (synthesizedMethod.IsGenericMethod) { synthesizedMethod = synthesizedMethod.Construct(immutableArray); } switch (closureKind) { case ClosureKind.Singleton: { FieldSymbol fieldSymbol = synthesizedClosureEnvironment.SingletonCache.AsMember(constructedFrame); receiver = new BoundFieldAccess(syntax, null, fieldSymbol, null); break; } case ClosureKind.Static: receiver = new BoundTypeExpression(syntax, null, synthesizedMethod.ContainingType); break; default: receiver = FrameOfType(syntax, constructedFrame); break; } } public override BoundNode VisitCall(BoundCall node) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if ((int)node.Method.MethodKind == 17) { ImmutableArray arguments = VisitList(node.Arguments); ImmutableArray argRefKinds = node.ArgumentRefKindsOpt; TypeSymbol type = VisitType(node.Type); RemapLocalFunction(node.Syntax, node.Method, out var receiver, out var method, ref arguments, ref argRefKinds); return node.Update(receiver, node.InitialBindingReceiverIsSubjectToCloning, method, arguments, node.ArgumentNamesOpt, argRefKinds, node.IsDelegateCall, node.Expanded, node.InvokedAsExtensionMethod, node.ArgsToParamsOpt, node.DefaultArguments, node.ResultKind, type); } BoundNode boundNode = base.VisitCall(node); if (boundNode.Kind != BoundKind.Call) { return boundNode; } BoundCall boundCall = (BoundCall)boundNode; if (!_seenBaseCall && _currentMethod == _topLevelMethod && node.IsConstructorInitializer()) { _seenBaseCall = true; if (_thisProxyInitDeferred != null) { return new BoundSequence(node.Syntax, ImmutableArray.Empty, ImmutableArray.Create((BoundExpression)boundCall), _thisProxyInitDeferred, boundCall.Type); } } return boundCall; } private BoundSequence RewriteSequence(BoundSequence node, ArrayBuilder prologue, ArrayBuilder newLocals) { RewriteLocals(node.Locals, newLocals); ImmutableArray.Enumerator enumerator = node.SideEffects.GetEnumerator(); while (enumerator.MoveNext()) { BoundExpression current = enumerator.Current; BoundExpression boundExpression = (BoundExpression)Visit(current); if (boundExpression != null) { prologue.Add(boundExpression); } } BoundExpression value = (BoundExpression)Visit(node.Value); TypeSymbol type = VisitType(node.Type); return node.Update(newLocals.ToImmutableAndFree(), prologue.ToImmutableAndFree(), value, type); } public override BoundNode VisitBlock(BoundBlock node) { if (_frames.TryGetValue(node, out var value)) { return IntroduceFrame(node, value, (ArrayBuilder prologue, ArrayBuilder newLocals) => RewriteBlock(node, prologue, newLocals)); } return RewriteBlock(node, ArrayBuilder.GetInstance(), ArrayBuilder.GetInstance()); } private BoundBlock RewriteBlock(BoundBlock node, ArrayBuilder prologue, ArrayBuilder newLocals) { RewriteLocals(node.Locals, newLocals); ArrayBuilder instance = ArrayBuilder.GetInstance(); if (prologue.Count > 0) { instance.Add(BoundSequencePoint.CreateHidden()); } InsertAndFreePrologue(instance, prologue); ImmutableArray.Enumerator enumerator = node.Statements.GetEnumerator(); while (enumerator.MoveNext()) { BoundStatement current = enumerator.Current; BoundStatement boundStatement = (BoundStatement)Visit(current); if (boundStatement != null) { instance.Add(boundStatement); } } BoundBlockInstrumentation boundBlockInstrumentation = node.Instrumentation; if (boundBlockInstrumentation != null) { BoundStatement prologue2 = (BoundStatement)Visit(boundBlockInstrumentation.Prologue); BoundStatement epilogue = (BoundStatement)Visit(boundBlockInstrumentation.Epilogue); boundBlockInstrumentation = boundBlockInstrumentation.Update(boundBlockInstrumentation.Local, prologue2, epilogue); } return node.Update(newLocals.ToImmutableAndFree(), node.LocalFunctions, node.HasUnsafeModifier, boundBlockInstrumentation, instance.ToImmutableAndFree()); } public override BoundNode VisitScope(BoundScope node) { ArrayBuilder instance = ArrayBuilder.GetInstance(); RewriteLocals(node.Locals, instance); ImmutableArray statements = VisitList(node.Statements); if (instance.Count == 0) { instance.Free(); return new BoundStatementList(node.Syntax, statements); } return node.Update(instance.ToImmutableAndFree(), statements); } public override BoundNode VisitCatchBlock(BoundCatchBlock node) { if (_frames.TryGetValue(node, out var value)) { return IntroduceFrame(node, value, (ArrayBuilder prologue, ArrayBuilder newLocals) => RewriteCatch(node, prologue, newLocals)); } return RewriteCatch(node, ArrayBuilder.GetInstance(), ArrayBuilder.GetInstance()); } private BoundNode RewriteCatch(BoundCatchBlock node, ArrayBuilder prologue, ArrayBuilder newLocals) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) RewriteLocals(node.Locals, newLocals); ImmutableArray locals = newLocals.ToImmutableAndFree(); BoundExpression boundExpression = null; BoundStatementList boundStatementList = (BoundStatementList)Visit(node.ExceptionFilterPrologueOpt); BoundExpression boundExpression2 = (BoundExpression)Visit(node.ExceptionFilterOpt); if (node.ExceptionSourceOpt != null) { boundExpression = (BoundExpression)Visit(node.ExceptionSourceOpt); if (prologue.Count > 0) { boundExpression = new BoundSequence(boundExpression.Syntax, ImmutableArray.Create(), prologue.ToImmutable(), boundExpression, boundExpression.Type); } } else if (prologue.Count > 0) { ArrayBuilder instance = ArrayBuilder.GetInstance(prologue.Count); Enumerator enumerator = prologue.GetEnumerator(); while (enumerator.MoveNext()) { BoundExpression current = enumerator.Current; instance.Add((BoundStatement)new BoundExpressionStatement(current.Syntax, current) { WasCompilerGenerated = true }); } if (boundStatementList != null) { instance.AddRange(boundStatementList.Statements); } boundStatementList = new BoundStatementList(boundExpression2.Syntax, instance.ToImmutableAndFree()); } prologue.Free(); TypeSymbol exceptionTypeOpt = VisitType(node.ExceptionTypeOpt); BoundBlock body = (BoundBlock)Visit(node.Body); return node.Update(locals, boundExpression, exceptionTypeOpt, boundStatementList, boundExpression2, body, node.IsSynthesizedAsyncCatchAll); } public override BoundNode VisitSequence(BoundSequence node) { if (_frames.TryGetValue(node, out var value)) { return IntroduceFrame(node, value, (ArrayBuilder prologue, ArrayBuilder newLocals) => RewriteSequence(node, prologue, newLocals)); } return RewriteSequence(node, ArrayBuilder.GetInstance(), ArrayBuilder.GetInstance()); } public override BoundNode VisitStatementList(BoundStatementList node) { if (_frames.TryGetValue(node, out var value)) { return IntroduceFrame(node, value, delegate(ArrayBuilder prologue, ArrayBuilder newLocals) { ArrayBuilder instance = ArrayBuilder.GetInstance(); InsertAndFreePrologue(instance, prologue); ImmutableArray.Enumerator enumerator = node.Statements.GetEnumerator(); while (enumerator.MoveNext()) { BoundStatement current = enumerator.Current; instance.Add((BoundStatement)Visit(current)); } return new BoundBlock(node.Syntax, newLocals.ToImmutableAndFree(), instance.ToImmutableAndFree(), node.HasErrors); }); } return base.VisitStatementList(node); } public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 if (node.Argument.Kind == BoundKind.Lambda) { return RewriteLambdaConversion((BoundLambda)node.Argument); } MethodSymbol? methodOpt = node.MethodOpt; if ((object)methodOpt != null && (int)methodOpt.MethodKind == 17) { ImmutableArray arguments = default(ImmutableArray); ImmutableArray argRefKinds = default(ImmutableArray); RemapLocalFunction(node.Syntax, node.MethodOpt, out var receiver, out var method, ref arguments, ref argRefKinds); return new BoundDelegateCreationExpression(node.Syntax, receiver, method, node.IsExtensionMethod, node.WasTargetTyped, VisitType(node.Type)); } return base.VisitDelegateCreationExpression(node); } public override BoundNode VisitFunctionPointerLoad(BoundFunctionPointerLoad node) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 if ((int)node.TargetMethod.MethodKind == 17) { ImmutableArray arguments = default(ImmutableArray); ImmutableArray argRefKinds = default(ImmutableArray); RemapLocalFunction(node.Syntax, node.TargetMethod, out var _, out var method, ref arguments, ref argRefKinds); return node.Update(method, node.ConstrainedToTypeOpt, node.Type); } return base.VisitFunctionPointerLoad(node); } public override BoundNode VisitConversion(BoundConversion conversion) { if (conversion.ConversionKind == ConversionKind.AnonymousFunction) { BoundExpression boundExpression = (BoundExpression)RewriteLambdaConversion((BoundLambda)conversion.Operand); if (_inExpressionLambda && conversion.ExplicitCastInCode) { boundExpression = new BoundConversion(conversion.Syntax, boundExpression, conversion.Conversion, isBaseConversion: false, @checked: false, explicitCastInCode: true, conversionGroupOpt: conversion.ConversionGroupOpt, constantValueOpt: conversion.ConstantValueOpt, type: conversion.Type); } return boundExpression; } return base.VisitConversion(conversion); } public override BoundNode VisitLocalFunctionStatement(BoundLocalFunctionStatement node) { RewriteLambdaOrLocalFunction(node, out var _, out var _, out var _, out var _, out var _, out var _); return new BoundNoOpStatement(node.Syntax, NoOpStatementFlavor.Default); } private DebugId GetLambdaId(SyntaxNode syntax, ClosureKind closureKind, int closureOrdinal) { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) SyntaxNode val; bool flag; if (syntax is AnonymousFunctionExpressionSyntax anonymousFunctionExpressionSyntax) { val = (SyntaxNode)(object)anonymousFunctionExpressionSyntax.Body; flag = true; } else if (syntax is LocalFunctionStatementSyntax localFunctionStatementSyntax) { val = (SyntaxNode)(((object)localFunctionStatementSyntax.Body) ?? ((object)localFunctionStatementSyntax.ExpressionBody?.Expression)); if (val == null) { val = (SyntaxNode)(object)localFunctionStatementSyntax; flag = false; } else { flag = true; } } else if (LambdaUtilities.IsQueryPairLambda(syntax)) { val = syntax; flag = false; } else { val = syntax; flag = true; } DebugId val2 = default(DebugId); DebugId val3 = default(DebugId); if (slotAllocatorOpt != null && slotAllocatorOpt.TryGetPreviousLambda(val, flag, ref val2)) { val3 = val2; } else { ((DebugId)(ref val3))._002Ector(_lambdaDebugInfoBuilder.Count, ((CommonPEModuleBuilder)CompilationState.ModuleBuilderOpt).CurrentGenerationOrdinal); } int num = _topLevelMethod.CalculateLocalSyntaxOffset(LambdaUtilities.GetDeclaratorPosition(val), val.SyntaxTree); _lambdaDebugInfoBuilder.Add(new LambdaDebugInfo(num, val3, closureOrdinal)); return val3; } private SynthesizedClosureMethod RewriteLambdaOrLocalFunction(IBoundLambdaOrFunction node, out ClosureKind closureKind, out NamedTypeSymbol translatedLambdaContainer, out SynthesizedClosureEnvironment containerAsFrame, out BoundNode lambdaScope, out DebugId topLevelMethodId, out DebugId lambdaId) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) Analysis.NestedFunction function = Analysis.GetNestedFunctionInTree(_analysis.ScopeTree, node.Symbol); SynthesizedClosureMethod synthesizedLoweredMethod = function.SynthesizedLoweredMethod; closureKind = synthesizedLoweredMethod.ClosureKind; translatedLambdaContainer = synthesizedLoweredMethod.ContainingType; containerAsFrame = translatedLambdaContainer as SynthesizedClosureEnvironment; topLevelMethodId = _analysis.GetTopLevelMethodId(); lambdaId = synthesizedLoweredMethod.LambdaId; if (function.ContainingEnvironmentOpt != null) { BoundNode tmpScope = null; Analysis.VisitScopeTree(_analysis.ScopeTree, delegate(Analysis.Scope scope) { if (scope.DeclaredEnvironment == function.ContainingEnvironmentOpt) { tmpScope = scope.BoundNode; } }); lambdaScope = tmpScope; } else { lambdaScope = null; } ((PEModuleBuilder)CompilationState.ModuleBuilderOpt).AddSynthesizedDefinition(translatedLambdaContainer, (IMethodDefinition)(object)synthesizedLoweredMethod.GetCciAdapter()); ImmutableArray.Enumerator enumerator = node.Symbol.Parameters.GetEnumerator(); while (enumerator.MoveNext()) { ParameterSymbol current = enumerator.Current; _parameterMap.Add(current, synthesizedLoweredMethod.Parameters[current.Ordinal]); } MethodSymbol currentMethod = _currentMethod; ParameterSymbol currentFrameThis = _currentFrameThis; ImmutableArray currentTypeParameters = _currentTypeParameters; Symbol innermostFramePointer = _innermostFramePointer; TypeMap currentLambdaBodyTypeMap = _currentLambdaBodyTypeMap; ArrayBuilder addedStatements = _addedStatements; ArrayBuilder addedLocals = _addedLocals; _addedStatements = null; _addedLocals = null; _currentMethod = synthesizedLoweredMethod; if (closureKind == ClosureKind.Static || closureKind == ClosureKind.Singleton) { _innermostFramePointer = (_currentFrameThis = null); } else { _currentFrameThis = synthesizedLoweredMethod.ThisParameter; _framePointers.TryGetValue(translatedLambdaContainer, out _innermostFramePointer); } SynthesizedClosureEnvironment obj = containerAsFrame; _currentTypeParameters = (((object)obj != null) ? ImmutableArrayExtensions.Concat(obj.TypeParameters, synthesizedLoweredMethod.TypeParameters) : synthesizedLoweredMethod.TypeParameters); _currentLambdaBodyTypeMap = synthesizedLoweredMethod.TypeMap; BoundBlock body = node.Body; if (body != null) { BoundStatement body2 = AddStatementsIfNeeded((BoundStatement)VisitBlock(body)); AddSynthesizedMethod(synthesizedLoweredMethod, body2); } _currentMethod = currentMethod; _currentFrameThis = currentFrameThis; _currentTypeParameters = currentTypeParameters; _innermostFramePointer = innermostFramePointer; _currentLambdaBodyTypeMap = currentLambdaBodyTypeMap; _addedLocals = addedLocals; _addedStatements = addedStatements; return synthesizedLoweredMethod; } private void AddSynthesizedMethod(MethodSymbol method, BoundStatement body) { if (_synthesizedMethods == null) { _synthesizedMethods = ArrayBuilder.GetInstance(); } _synthesizedMethods.Add(new TypeCompilationState.MethodWithBody(method, body, CompilationState.CurrentImportChain)); } private BoundNode RewriteLambdaConversion(BoundLambda node) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Invalid comparison between Unknown and I4 //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) bool inExpressionLambda = _inExpressionLambda; _inExpressionLambda = _inExpressionLambda || node.Type.IsExpressionTree(); if (_inExpressionLambda) { TypeSymbol type = VisitType(node.Type); BoundBlock body = (BoundBlock)Visit(node.Body); node = node.Update(node.UnboundLambda, node.Symbol, body, node.Diagnostics, node.Binder, type); BoundNode result = (inExpressionLambda ? node : ExpressionLambdaRewriter.RewriteLambda(node, CompilationState, TypeMap, base.RecursionDepth, Diagnostics)); _inExpressionLambda = inExpressionLambda; return result; } ClosureKind closureKind; NamedTypeSymbol translatedLambdaContainer; SynthesizedClosureEnvironment containerAsFrame; BoundNode lambdaScope; DebugId topLevelMethodId; DebugId lambdaId; MethodSymbol synthesizedMethod = RewriteLambdaOrLocalFunction(node, out closureKind, out translatedLambdaContainer, out containerAsFrame, out lambdaScope, out topLevelMethodId, out lambdaId); RemapLambdaOrLocalFunction(node.Syntax, node.Symbol, default(ImmutableArray), closureKind, ref synthesizedMethod, out var receiver, out var constructedFrame); TypeSymbol type2 = VisitType(node.Type); BoundExpression boundExpression = new BoundDelegateCreationExpression(node.Syntax, receiver, synthesizedMethod, isExtensionMethod: false, wasTargetTyped: false, type2); bool flag = closureKind == ClosureKind.Singleton && (int)_currentMethod.MethodKind != 14 && !synthesizedMethod.IsGenericMethod; bool flag2 = lambdaScope != null && lambdaScope != Analysis.GetScopeParent(_analysis.ScopeTree, node.Body).BoundNode && InLoopOrLambda(node.Syntax, lambdaScope.Syntax); if (flag || flag2) { SyntheticBoundNodeFactory syntheticBoundNodeFactory = new SyntheticBoundNodeFactory(_currentMethod, node.Syntax, CompilationState, Diagnostics); try { if (flag || (flag2 && (object)containerAsFrame != null)) { TypeSymbol type3 = containerAsFrame.TypeMap.SubstituteType(node.Type).Type; if (!type3.ContainsMethodTypeParameter()) { string name = GeneratedNames.MakeLambdaCacheFieldName((closureKind == ClosureKind.General) ? (-1) : topLevelMethodId.Ordinal, topLevelMethodId.Generation, lambdaId.Ordinal, lambdaId.Generation); SynthesizedLambdaCacheFieldSymbol synthesizedLambdaCacheFieldSymbol = new SynthesizedLambdaCacheFieldSymbol(translatedLambdaContainer, type3, name, _topLevelMethod, isReadOnly: false, closureKind == ClosureKind.Singleton); ((PEModuleBuilder)CompilationState.ModuleBuilderOpt).AddSynthesizedDefinition(translatedLambdaContainer, (IFieldDefinition)(object)synthesizedLambdaCacheFieldSymbol.GetCciAdapter()); BoundExpression left = syntheticBoundNodeFactory.Field(receiver, synthesizedLambdaCacheFieldSymbol.AsMember(constructedFrame)); boundExpression = syntheticBoundNodeFactory.Coalesce(left, syntheticBoundNodeFactory.AssignmentExpression(left, boundExpression)); } } else { LocalSymbol localSymbol = syntheticBoundNodeFactory.SynthesizedLocal(type2, null, isPinned: false, isKnownToReferToTempIfReferenceType: false, (RefKind)0, (SynthesizedLocalKind)31); if (_addedLocals == null) { _addedLocals = ArrayBuilder.GetInstance(); } _addedLocals.Add(localSymbol); if (_addedStatements == null) { _addedStatements = ArrayBuilder.GetInstance(); } BoundExpression left = syntheticBoundNodeFactory.Local(localSymbol); _addedStatements.Add((BoundStatement)syntheticBoundNodeFactory.Assignment(left, syntheticBoundNodeFactory.Null(type2))); boundExpression = syntheticBoundNodeFactory.Coalesce(left, syntheticBoundNodeFactory.AssignmentExpression(left, boundExpression)); } } catch (SyntheticBoundNodeFactory.MissingPredefinedMember missingPredefinedMember) { ((BindingDiagnosticBag)Diagnostics).Add(missingPredefinedMember.Diagnostic); return new BoundBadExpression(syntheticBoundNodeFactory.Syntax, LookupResultKind.Empty, ImmutableArray.Empty, ImmutableArray.Create((BoundExpression)node), node.Type); } } return boundExpression; } private static bool InLoopOrLambda(SyntaxNode lambdaSyntax, SyntaxNode scopeSyntax) { SyntaxNode parent = lambdaSyntax.Parent; while (parent != null && parent != scopeSyntax) { SyntaxKind syntaxKind = parent.Kind(); if (syntaxKind - 8642 <= SyntaxKind.List || syntaxKind - 8809 <= (SyntaxKind)3 || syntaxKind == SyntaxKind.ForEachVariableStatement) { return true; } parent = parent.Parent; } return false; } public override BoundNode VisitLambda(BoundLambda node) { throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/ClosureConversion.cs", 1764); } }