using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Reflection.Metadata; using System.Runtime.CompilerServices; using System.Threading; using Microsoft.Cci; using Microsoft.CodeAnalysis.CSharp.Emit; 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.Symbols; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.CodeGen; internal sealed class CodeGenerator { private enum IndirectReturnState : byte { NotNeeded, Needed, Emitted } private enum ArrayInitializerStyle { Element, Block, Mixed } private readonly struct IndexDesc(int index, ImmutableArray initializers) { public readonly int Index = index; public readonly ImmutableArray Initializers = initializers; } private class EmitCancelledException : Exception { } private enum UseKind { Unused, UsedAsValue, UsedAsAddress } private sealed class IsConditionalConstrainedCallThatMustUseTempForReferenceTypeReceiverWalker : BoundTreeWalkerWithStackGuardWithoutRecursionOnTheLeftOfBinaryOperator { private readonly BoundLoweredConditionalAccess _conditionalAccess; private bool? _result; private IsConditionalConstrainedCallThatMustUseTempForReferenceTypeReceiverWalker(BoundLoweredConditionalAccess conditionalAccess) { _conditionalAccess = conditionalAccess; } public static bool Analyze(BoundLoweredConditionalAccess conditionalAccess) { IsConditionalConstrainedCallThatMustUseTempForReferenceTypeReceiverWalker isConditionalConstrainedCallThatMustUseTempForReferenceTypeReceiverWalker = new IsConditionalConstrainedCallThatMustUseTempForReferenceTypeReceiverWalker(conditionalAccess); isConditionalConstrainedCallThatMustUseTempForReferenceTypeReceiverWalker.Visit(conditionalAccess.WhenNotNull); return isConditionalConstrainedCallThatMustUseTempForReferenceTypeReceiverWalker._result == true; } public override BoundNode Visit(BoundNode node) { if (_result.HasValue) { return null; } return base.Visit(node); } protected override void VisitReceiver(BoundCall node) { if (node.ReceiverOpt is BoundConditionalReceiver { Id: var id } && id == _conditionalAccess.Id) { _result = !IsSafeToDereferenceReceiverRefAfterEvaluatingArguments(node.Arguments); } } public override BoundNode VisitConditionalReceiver(BoundConditionalReceiver node) { if (node.Id == _conditionalAccess.Id) { _result = false; return null; } return base.VisitConditionalReceiver(node); } } private enum CallKind { Call, CallVirt, ConstrainedCallVirt } private class FinallyCloner : BoundTreeRewriterWithStackGuardWithoutRecursionOnTheLeftOfBinaryOperator { private Dictionary _labelClones; private FinallyCloner() { } public static BoundBlock MakeFinallyClone(BoundTryStatement node) { return (BoundBlock)new FinallyCloner().Visit(node.FinallyBlockOpt); } public override BoundNode VisitLabelStatement(BoundLabelStatement node) { return node.Update(GetLabelClone(node.Label)); } public override BoundNode VisitGotoStatement(BoundGotoStatement node) { GeneratedLabelSymbol labelClone = GetLabelClone(node.Label); BoundExpression caseExpressionOpt = node.CaseExpressionOpt; BoundLabel labelExpressionOpt = node.LabelExpressionOpt; return node.Update(labelClone, caseExpressionOpt, labelExpressionOpt); } public override BoundNode VisitConditionalGoto(BoundConditionalGoto node) { GeneratedLabelSymbol labelClone = GetLabelClone(node.Label); BoundExpression condition = node.Condition; return node.Update(condition, node.JumpIfTrue, labelClone); } public override BoundNode VisitSwitchDispatch(BoundSwitchDispatch node) { BoundExpression expression = node.Expression; GeneratedLabelSymbol labelClone = GetLabelClone(node.DefaultLabel); ArrayBuilder<(ConstantValue, LabelSymbol)> instance = ArrayBuilder<(ConstantValue, LabelSymbol)>.GetInstance(); ImmutableArray<(ConstantValue, LabelSymbol)>.Enumerator enumerator = node.Cases.GetEnumerator(); while (enumerator.MoveNext()) { var (item, label) = enumerator.Current; instance.Add((item, (LabelSymbol)GetLabelClone(label))); } LengthBasedStringSwitchData lengthBasedStringSwitchDataOpt = node.LengthBasedStringSwitchDataOpt; if (lengthBasedStringSwitchDataOpt != null) { throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/CodeGen/EmitStatement.cs", 1965); } return node.Update(expression, instance.ToImmutableAndFree(), labelClone, lengthBasedStringSwitchDataOpt); } public override BoundNode VisitExpressionStatement(BoundExpressionStatement node) { return node; } private GeneratedLabelSymbol GetLabelClone(LabelSymbol label) { Dictionary dictionary = _labelClones; if (dictionary == null) { dictionary = (_labelClones = new Dictionary()); } if (!dictionary.TryGetValue(label, out var value)) { value = new GeneratedLabelSymbol("cloned_" + label.Name); dictionary.Add(label, value); } return value; } } [CompilerGenerated] private static class _003C_003EO { public static Func _003C0_003E__isSafeToDereferenceReceiverRefAfterEvaluatingArgument; public static GetStringHashCode _003C1_003E__ComputeStringHash; } private readonly MethodSymbol _method; private readonly SyntaxNode _methodBodySyntaxOpt; private readonly BoundStatement _boundBody; private readonly ILBuilder _builder; private readonly PEModuleBuilder _module; private readonly BindingDiagnosticBag _diagnostics; private readonly ILEmitStyle _ilEmitStyle; private readonly bool _emitPdbSequencePoints; private readonly HashSet _stackLocals; private ArrayBuilder _expressionTemps; private int _tryNestingLevel; private readonly SynthesizedLocalOrdinalsDispenser _synthesizedLocalOrdinals = new SynthesizedLocalOrdinalsDispenser(); private int _uniqueNameId; private static readonly object s_returnLabel = new object(); private int _asyncCatchHandlerOffset = -1; private ArrayBuilder _asyncYieldPoints; private ArrayBuilder _asyncResumePoints; private IndirectReturnState _indirectReturnState; private PooledDictionary _savedSequencePoints; private LocalDefinition _returnTemp; private bool _sawStackalloc; private int _recursionDepth; private static readonly ILOpCode[] s_compOpCodes = new ILOpCode[12] { ILOpCode.Clt, ILOpCode.Cgt, ILOpCode.Cgt, ILOpCode.Clt, ILOpCode.Clt_un, ILOpCode.Cgt_un, ILOpCode.Cgt_un, ILOpCode.Clt_un, ILOpCode.Clt, ILOpCode.Cgt_un, ILOpCode.Cgt, ILOpCode.Clt_un }; private const int IL_OP_CODE_ROW_LENGTH = 4; private static readonly ILOpCode[] s_condJumpOpCodes = new ILOpCode[24] { ILOpCode.Blt, ILOpCode.Ble, ILOpCode.Bgt, ILOpCode.Bge, ILOpCode.Bge, ILOpCode.Bgt, ILOpCode.Ble, ILOpCode.Blt, ILOpCode.Blt_un, ILOpCode.Ble_un, ILOpCode.Bgt_un, ILOpCode.Bge_un, ILOpCode.Bge_un, ILOpCode.Bgt_un, ILOpCode.Ble_un, ILOpCode.Blt_un, ILOpCode.Blt, ILOpCode.Ble, ILOpCode.Bgt, ILOpCode.Bge, ILOpCode.Bge_un, ILOpCode.Bgt_un, ILOpCode.Ble_un, ILOpCode.Blt_un }; private LocalDefinition LazyReturnTemp { get { //IL_0013: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) LocalDefinition val = _returnTemp; if (val == null) { LocalSlotConstraints val2 = (LocalSlotConstraints)(((int)_method.RefKind != 0) ? 1 : 0); SyntaxNode methodBodySyntaxOpt = _methodBodySyntaxOpt; if ((int)_ilEmitStyle == 0 && methodBodySyntaxOpt != null) { int num = _method.CalculateLocalSyntaxOffset(LambdaUtilities.GetDeclaratorPosition(methodBodySyntaxOpt), methodBodySyntaxOpt.SyntaxTree); SynthesizedLocal synthesizedLocal = new SynthesizedLocal(_method, _method.ReturnTypeWithAnnotations, (SynthesizedLocalKind)21, methodBodySyntaxOpt, isPinned: false, isKnownToReferToTempIfReferenceType: false, (RefKind)0); val = _builder.LocalSlotManager.DeclareLocal(((PEModuleBuilder)_module).Translate(synthesizedLocal.Type, methodBodySyntaxOpt, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag), (ILocalSymbolInternal)(object)synthesizedLocal, (string)null, synthesizedLocal.SynthesizedKind, new LocalDebugId(num, 0), SynthesizedLocalKindExtensions.PdbAttributes(synthesizedLocal.SynthesizedKind), val2, ImmutableArray.Empty, ImmutableArray.Empty, false); } else { val = AllocateTemp(_method.ReturnType, _boundBody.Syntax, val2); } _returnTemp = val; } return val; } } private bool EnableEnumArrayBlockInitialization => ((PEModuleBuilder)_module).Compilation.EnableEnumArrayBlockInitialization; public CodeGenerator(MethodSymbol method, BoundStatement boundBody, ILBuilder builder, PEModuleBuilder moduleBuilder, BindingDiagnosticBag diagnostics, OptimizationLevel optimizations, bool emittingPdb) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_004e: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Invalid comparison between Unknown and I4 _method = method; _boundBody = boundBody; _builder = builder; _module = moduleBuilder; _diagnostics = diagnostics; if (!method.GenerateDebugInfo) { _ilEmitStyle = (ILEmitStyle)2; } else if ((int)optimizations == 0) { _ilEmitStyle = (ILEmitStyle)0; } else { _ilEmitStyle = (ILEmitStyle)(IsDebugPlus() ? 1 : 2); } _emitPdbSequencePoints = emittingPdb && method.GenerateDebugInfo; try { _boundBody = Optimizer.Optimize(boundBody, (int)_ilEmitStyle != 2, out _stackLocals); } catch (BoundTreeVisitor.CancelledByStackGuardException ex) { ex.AddAnError(diagnostics); _boundBody = boundBody; } SourceMemberMethodSymbol sourceMemberMethodSymbol = method as SourceMemberMethodSymbol; (BlockSyntax blockBody, ArrowExpressionClauseSyntax arrowBody) obj = sourceMemberMethodSymbol?.Bodies ?? default((BlockSyntax, ArrowExpressionClauseSyntax)); BlockSyntax item = obj.blockBody; ArrowExpressionClauseSyntax item2 = obj.arrowBody; _methodBodySyntaxOpt = (SyntaxNode)(object)(item ?? item2 ?? sourceMemberMethodSymbol?.SyntaxNode); } private bool IsDebugPlus() { return ((CompilationOptions)((PEModuleBuilder)_module).Compilation.Options).DebugPlusMode; } private bool IsPeVerifyCompatEnabled() { return ((PEModuleBuilder)_module).Compilation.IsPeVerifyCompatEnabled; } internal static bool IsStackLocal(LocalSymbol local, HashSet stackLocalsOpt) { return stackLocalsOpt?.Contains(local) ?? false; } private bool IsStackLocal(LocalSymbol local) { return IsStackLocal(local, _stackLocals); } public void Generate(out bool hasStackalloc) { GenerateImpl(); hasStackalloc = _sawStackalloc; } public void Generate(out int asyncCatchHandlerOffset, out ImmutableArray asyncYieldPoints, out ImmutableArray asyncResumePoints, out bool hasStackAlloc) { GenerateImpl(); hasStackAlloc = _sawStackalloc; asyncCatchHandlerOffset = (((BindingDiagnosticBag)_diagnostics).HasAnyErrors() ? (-1) : _builder.GetILOffsetFromMarker(_asyncCatchHandlerOffset)); ArrayBuilder asyncYieldPoints2 = _asyncYieldPoints; ArrayBuilder asyncResumePoints2 = _asyncResumePoints; if (asyncYieldPoints2 == null || ((BindingDiagnosticBag)_diagnostics).HasAnyErrors()) { asyncYieldPoints = ImmutableArray.Empty; asyncResumePoints = ImmutableArray.Empty; return; } ArrayBuilder instance = ArrayBuilder.GetInstance(); ArrayBuilder instance2 = ArrayBuilder.GetInstance(); int count = asyncYieldPoints2.Count; for (int i = 0; i < count; i++) { int iLOffsetFromMarker = _builder.GetILOffsetFromMarker(asyncYieldPoints2[i]); int iLOffsetFromMarker2 = _builder.GetILOffsetFromMarker(asyncResumePoints2[i]); if (iLOffsetFromMarker > 0) { instance.Add(iLOffsetFromMarker); instance2.Add(iLOffsetFromMarker2); } } asyncYieldPoints = instance.ToImmutableAndFree(); asyncResumePoints = instance2.ToImmutableAndFree(); asyncYieldPoints2.Free(); asyncResumePoints2.Free(); } private void GenerateImpl() { SetInitialDebugDocument(); if (_emitPdbSequencePoints && _method.IsImplicitlyDeclared) { _builder.DefineInitialHiddenSequencePoint(); } try { EmitStatement(_boundBody); if (_indirectReturnState == IndirectReturnState.Needed) { HandleReturn(); } if (!((BindingDiagnosticBag)_diagnostics).HasAnyErrors()) { _builder.Realize(); } } catch (EmitCancelledException) { } _synthesizedLocalOrdinals.Free(); _expressionTemps?.Free(); _savedSequencePoints?.Free(); } private void HandleReturn() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) _builder.MarkLabel(s_returnLabel); if (_emitPdbSequencePoints && !_method.IsIterator && !_method.IsAsync && _methodBodySyntaxOpt is BlockSyntax blockSyntax) { SyntaxTree syntaxTree = blockSyntax.SyntaxTree; SyntaxToken closeBraceToken = blockSyntax.CloseBraceToken; EmitSequencePoint(syntaxTree, ((SyntaxToken)(ref closeBraceToken)).Span); } if (_returnTemp != null) { _builder.EmitLocalLoad(LazyReturnTemp); _builder.EmitRet(false); } else { _builder.EmitRet(true); } _indirectReturnState = IndirectReturnState.Emitted; } private void EmitTypeReferenceToken(ITypeReference symbol, SyntaxNode syntaxNode) { _builder.EmitToken((IReference)(object)symbol, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag, (RawTokenEncoding)0); } private void EmitSymbolToken(TypeSymbol symbol, SyntaxNode syntaxNode) { EmitTypeReferenceToken(((PEModuleBuilder)_module).Translate(symbol, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag), syntaxNode); } private void EmitSymbolToken(MethodSymbol method, SyntaxNode syntaxNode, BoundArgListOperator optArgList, bool encodeAsRawDefinitionToken = false) { IMethodReference val = _module.Translate(method, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag, optArgList, encodeAsRawDefinitionToken); _builder.EmitToken((IReference)(object)val, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag, (RawTokenEncoding)(encodeAsRawDefinitionToken ? 1 : 0)); } private void EmitSymbolToken(FieldSymbol symbol, SyntaxNode syntaxNode) { IFieldReference val = _module.Translate(symbol, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); _builder.EmitToken((IReference)(object)val, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag, (RawTokenEncoding)0); } private void EmitSignatureToken(FunctionPointerTypeSymbol symbol, SyntaxNode syntaxNode) { _builder.EmitToken(_module.Translate(symbol).Signature, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); } private void EmitSequencePointStatement(BoundSequencePoint node) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) SyntaxNode syntax = node.Syntax; if (_emitPdbSequencePoints) { if (syntax == null) { EmitHiddenSequencePoint(); } else { EmitSequencePoint(syntax); } } BoundStatement statementOpt = node.StatementOpt; int num = 0; if (statementOpt != null) { num = EmitStatementAndCountInstructions(statementOpt); } if (num == 0 && syntax != null && (int)_ilEmitStyle == 0) { _builder.EmitOpCode(ILOpCode.Nop); } } private void EmitSequencePointStatement(BoundSequencePointWithSpan node) { //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_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0045: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) TextSpan span = node.Span; if (span != default(TextSpan) && _emitPdbSequencePoints) { EmitSequencePoint(node.SyntaxTree, span); } BoundStatement statementOpt = node.StatementOpt; int num = 0; if (statementOpt != null) { num = EmitStatementAndCountInstructions(statementOpt); } if (num == 0 && span != default(TextSpan) && (int)_ilEmitStyle == 0) { _builder.EmitOpCode(ILOpCode.Nop); } } private void EmitSavePreviousSequencePoint(BoundSavePreviousSequencePoint statement) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_0032: 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) if (!_emitPdbSequencePoints) { return; } ArrayBuilder seqPointsOpt = _builder.SeqPointsOpt; if (seqPointsOpt == null) { return; } for (int num = seqPointsOpt.Count - 1; num >= 0; num--) { TextSpan span = seqPointsOpt[num].Span; if (!(span == RawSequencePoint.HiddenSequencePointSpan)) { if (_savedSequencePoints == null) { _savedSequencePoints = PooledDictionary.GetInstance(); } ((Dictionary)(object)_savedSequencePoints).Add(statement.Identifier, span); break; } } } private void EmitRestorePreviousSequencePoint(BoundRestorePreviousSequencePoint node) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (_savedSequencePoints != null && ((Dictionary)(object)_savedSequencePoints).TryGetValue(node.Identifier, out TextSpan value)) { EmitStepThroughSequencePoint(node.Syntax.SyntaxTree, value); } } private void EmitStepThroughSequencePoint(BoundStepThroughSequencePoint node) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) EmitStepThroughSequencePoint(node.Syntax.SyntaxTree, node.Span); } private void EmitStepThroughSequencePoint(SyntaxTree syntaxTree, TextSpan span) { //IL_0031: 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) if (_emitPdbSequencePoints) { object obj = new object(); _builder.EmitConstantValue(ConstantValue.Create(true)); _builder.EmitBranch(ILOpCode.Brtrue, obj, ILOpCode.Nop); EmitSequencePoint(syntaxTree, span); _builder.EmitOpCode(ILOpCode.Nop); _builder.MarkLabel(obj); EmitHiddenSequencePoint(); } } private void SetInitialDebugDocument() { if (_emitPdbSequencePoints && _methodBodySyntaxOpt != null) { _builder.SetInitialDebugDocument(_methodBodySyntaxOpt.SyntaxTree); } } private void EmitHiddenSequencePoint() { _builder.DefineHiddenSequencePoint(); } private void EmitSequencePoint(SyntaxNode syntax) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) EmitSequencePoint(syntax.SyntaxTree, syntax.Span); } private TextSpan EmitSequencePoint(SyntaxTree syntaxTree, TextSpan span) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) _builder.DefineSequencePoint(syntaxTree, span); return span; } private void AddExpressionTemp(LocalDefinition temp) { if (temp != null) { ArrayBuilder val = _expressionTemps; if (val == null) { val = (_expressionTemps = ArrayBuilder.GetInstance()); } val.Add(temp); } } private void ReleaseExpressionTemps() { ArrayBuilder expressionTemps = _expressionTemps; if (expressionTemps != null && expressionTemps.Count > 0) { for (int num = _expressionTemps.Count - 1; num >= 0; num--) { LocalDefinition temp = _expressionTemps[num]; FreeTemp(temp); } _expressionTemps.Clear(); } } private LocalDefinition EmitAddress(BoundExpression expression, Binder.AddressKind addressKind) { //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Invalid comparison between Unknown and I4 //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Invalid comparison between Unknown and I4 switch (expression.Kind) { case BoundKind.RefValueOperator: EmitRefValueAddress((BoundRefValueOperator)expression); break; case BoundKind.Local: return EmitLocalAddress((BoundLocal)expression, addressKind); case BoundKind.Dup: return EmitDupAddress((BoundDup)expression, addressKind); case BoundKind.ComplexConditionalReceiver: EmitComplexConditionalReceiverAddress((BoundComplexConditionalReceiver)expression); break; case BoundKind.Parameter: return EmitParameterAddress((BoundParameter)expression, addressKind); case BoundKind.FieldAccess: return EmitFieldAddress((BoundFieldAccess)expression, addressKind); case BoundKind.ArrayAccess: if (HasHome(expression, addressKind)) { EmitArrayElementAddress((BoundArrayAccess)expression, addressKind); break; } goto default; case BoundKind.ThisReference: if (expression.Type.IsValueType) { if (HasHome(expression, addressKind)) { _builder.EmitLoadArgumentOpcode(0); break; } goto default; } _builder.EmitLoadArgumentAddrOpcode(0); break; case BoundKind.PreviousSubmissionReference: throw ExceptionUtilities.UnexpectedValue((object)expression.Kind); case BoundKind.PassByCopy: return EmitPassByCopyAddress((BoundPassByCopy)expression, addressKind); case BoundKind.Sequence: return EmitSequenceAddress((BoundSequence)expression, addressKind); case BoundKind.PointerIndirectionOperator: { BoundExpression operand = ((BoundPointerIndirectionOperator)expression).Operand; EmitExpression(operand, used: true); break; } case BoundKind.PseudoVariable: EmitPseudoVariableAddress((BoundPseudoVariable)expression); break; case BoundKind.Call: { BoundCall call = (BoundCall)expression; if (UseCallResultAsAddress(call, addressKind)) { EmitCallExpression(call, UseKind.UsedAsAddress); break; } goto default; } case BoundKind.FunctionPointerInvocation: { BoundFunctionPointerInvocation boundFunctionPointerInvocation = (BoundFunctionPointerInvocation)expression; RefKind refKind = boundFunctionPointerInvocation.FunctionPointer.Signature.RefKind; if ((int)refKind == 1 || (Binder.IsAnyReadOnly(addressKind) && (int)refKind == 3)) { EmitCalli(boundFunctionPointerInvocation, UseKind.UsedAsAddress); break; } goto default; } case BoundKind.DefaultExpression: { TypeSymbol type = expression.Type; LocalDefinition val = AllocateTemp(type, expression.Syntax, (LocalSlotConstraints)0); _builder.EmitLocalAddress(val); _builder.EmitOpCode(ILOpCode.Dup); _builder.EmitOpCode(ILOpCode.Initobj); EmitSymbolToken(type, expression.Syntax); return val; } case BoundKind.ConditionalOperator: if (HasHome(expression, addressKind)) { EmitConditionalOperatorAddress((BoundConditionalOperator)expression, addressKind); break; } goto default; case BoundKind.AssignmentOperator: { BoundAssignmentOperator boundAssignmentOperator = (BoundAssignmentOperator)expression; if (boundAssignmentOperator.IsRef && HasHome(boundAssignmentOperator, addressKind)) { EmitAssignmentExpression(boundAssignmentOperator, UseKind.UsedAsAddress); break; } goto default; } case BoundKind.ThrowExpression: EmitExpression(expression, used: true); return null; default: return EmitAddressOfTempClone(expression); case BoundKind.BaseReference: case BoundKind.ConditionalReceiver: break; } return null; } private static bool UseCallResultAsAddress(BoundCall call, Binder.AddressKind addressKind) { //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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 RefKind refKind = call.Method.RefKind; if ((int)refKind != 1) { if (Binder.IsAnyReadOnly(addressKind)) { return (int)refKind == 3; } return false; } return true; } private LocalDefinition EmitPassByCopyAddress(BoundPassByCopy passByCopyExpr, Binder.AddressKind addressKind) { if (passByCopyExpr.Expression is BoundSequence boundSequence && DigForValueLocal(boundSequence, boundSequence.Value) != null) { return EmitSequenceAddress(boundSequence, addressKind); } return EmitAddressOfTempClone(passByCopyExpr); } private void EmitConditionalOperatorAddress(BoundConditionalOperator expr, Binder.AddressKind addressKind) { object dest = new object(); object obj = new object(); EmitCondBranch(expr.Condition, ref dest, sense: true); AddExpressionTemp(EmitAddress(expr.Alternative, addressKind)); _builder.EmitBranch(ILOpCode.Br, obj, ILOpCode.Nop); _builder.AdjustStack(-1); _builder.MarkLabel(dest); AddExpressionTemp(EmitAddress(expr.Consequence, addressKind)); _builder.MarkLabel(obj); } private void EmitComplexConditionalReceiverAddress(BoundComplexConditionalReceiver expression) { TypeSymbol type = expression.Type; object obj = new object(); object obj2 = new object(); EmitInitObj(type, used: true, expression.Syntax); EmitBox(type, expression.Syntax); _builder.EmitBranch(ILOpCode.Brtrue, obj, ILOpCode.Nop); EmitAddress(expression.ReferenceTypeReceiver, Binder.AddressKind.ReadOnly); _builder.EmitBranch(ILOpCode.Br, obj2, ILOpCode.Nop); _builder.AdjustStack(-1); _builder.MarkLabel(obj); EmitReceiverRef(expression.ValueTypeReceiver, Binder.AddressKind.Constrained); _builder.MarkLabel(obj2); } private LocalDefinition EmitLocalAddress(BoundLocal localAccess, Binder.AddressKind addressKind) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) LocalSymbol localSymbol = localAccess.LocalSymbol; if (!HasHome(localAccess, addressKind)) { return EmitAddressOfTempClone(localAccess); } if (IsStackLocal(localSymbol)) { if ((int)localSymbol.RefKind == 0) { throw ExceptionUtilities.UnexpectedValue((object)localSymbol.RefKind); } } else { _builder.EmitLocalAddress(GetLocal(localAccess)); } return null; } private LocalDefinition EmitDupAddress(BoundDup dup, Binder.AddressKind addressKind) { if (!HasHome(dup, addressKind)) { return EmitAddressOfTempClone(dup); } _builder.EmitOpCode(ILOpCode.Dup); return null; } private void EmitPseudoVariableAddress(BoundPseudoVariable expression) { EmitExpression(expression.EmitExpressions.GetAddress(expression), used: true); } private void EmitRefValueAddress(BoundRefValueOperator refValue) { EmitExpression(refValue.Operand, used: true); _builder.EmitOpCode(ILOpCode.Refanyval); EmitSymbolToken(refValue.Type, refValue.Syntax); } private LocalDefinition EmitAddressOfTempClone(BoundExpression expression) { EmitExpression(expression, used: true); LocalDefinition val = AllocateTemp(expression.Type, expression.Syntax, (LocalSlotConstraints)0); _builder.EmitLocalStore(val); _builder.EmitLocalAddress(val); return val; } private LocalDefinition EmitSequenceAddress(BoundSequence sequence, Binder.AddressKind addressKind) { DefineAndRecordLocals(sequence); EmitSideEffects(sequence); LocalDefinition result = EmitAddress(sequence.Value, addressKind); CloseScopeAndKeepLocals(sequence); return result; } private static LocalSymbol DigForValueLocal(BoundSequence topSequence, BoundExpression value) { switch (value.Kind) { case BoundKind.Local: { LocalSymbol localSymbol = ((BoundLocal)value).LocalSymbol; if (topSequence.Locals.Contains(localSymbol)) { return localSymbol; } break; } case BoundKind.Sequence: return DigForValueLocal(topSequence, ((BoundSequence)value).Value); case BoundKind.FieldAccess: { BoundFieldAccess boundFieldAccess = (BoundFieldAccess)value; if (!boundFieldAccess.FieldSymbol.IsStatic) { BoundExpression receiverOpt = boundFieldAccess.ReceiverOpt; if (!receiverOpt.Type.IsReferenceType) { return DigForValueLocal(topSequence, receiverOpt); } } break; } } return null; } private void EmitArrayIndices(ImmutableArray indices) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < indices.Length; i++) { BoundExpression boundExpression = indices[i]; EmitExpression(boundExpression, used: true); TreatLongsAsNative(boundExpression.Type.PrimitiveTypeCode); } } private void EmitArrayElementAddress(BoundArrayAccess arrayAccess, Binder.AddressKind addressKind) { EmitExpression(arrayAccess.Expression, used: true); EmitArrayIndices(arrayAccess.Indices); if (ShouldEmitReadOnlyPrefix(arrayAccess, addressKind)) { _builder.EmitOpCode(ILOpCode.Readonly); } if (((ArrayTypeSymbol)arrayAccess.Expression.Type).IsSZArray) { _builder.EmitOpCode(ILOpCode.Ldelema); TypeSymbol type = arrayAccess.Type; EmitSymbolToken(type, arrayAccess.Syntax); } else { _builder.EmitArrayElementAddress(_module.Translate((ArrayTypeSymbol)arrayAccess.Expression.Type), arrayAccess.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); } } private bool ShouldEmitReadOnlyPrefix(BoundArrayAccess arrayAccess, Binder.AddressKind addressKind) { if (addressKind == Binder.AddressKind.Constrained) { return true; } if (!Binder.IsAnyReadOnly(addressKind)) { return false; } return !arrayAccess.Type.IsValueType; } private LocalDefinition EmitFieldAddress(BoundFieldAccess fieldAccess, Binder.AddressKind addressKind) { FieldSymbol fieldSymbol = fieldAccess.FieldSymbol; if (!HasHome(fieldAccess, addressKind)) { return EmitAddressOfTempClone(fieldAccess); } if (fieldAccess.FieldSymbol.IsStatic) { EmitStaticFieldAddress(fieldSymbol, fieldAccess.Syntax); return null; } return EmitInstanceFieldAddress(fieldAccess, addressKind); } private void EmitStaticFieldAddress(FieldSymbol field, SyntaxNode syntaxNode) { _builder.EmitOpCode(ILOpCode.Ldsflda); EmitSymbolToken(field, syntaxNode); } private bool HasHome(BoundExpression expression, Binder.AddressKind addressKind) { return Binder.HasHome(expression, addressKind, _method, IsPeVerifyCompatEnabled(), _stackLocals); } private LocalDefinition EmitParameterAddress(BoundParameter parameter, Binder.AddressKind addressKind) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) ParameterSymbol parameterSymbol = parameter.ParameterSymbol; if (!HasHome(parameter, addressKind)) { return EmitAddressOfTempClone(parameter); } int num = ParameterSlot(parameter); if ((int)parameterSymbol.RefKind == 0) { _builder.EmitLoadArgumentAddrOpcode(num); } else { _builder.EmitLoadArgumentOpcode(num); } return null; } private LocalDefinition EmitReceiverRef(BoundExpression receiver, Binder.AddressKind addressKind) { TypeSymbol type = receiver.Type; if (type.IsVerifierReference()) { EmitExpression(receiver, used: true); return null; } if (BoxNonVerifierReferenceReceiver(type, addressKind)) { EmitExpression(receiver, used: true); if (receiver.Kind != BoundKind.ConditionalReceiver) { EmitBox(receiver.Type, receiver.Syntax); } return null; } return EmitAddress(receiver, addressKind); } private static bool BoxNonVerifierReferenceReceiver(TypeSymbol receiverType, Binder.AddressKind addressKind) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if ((int)receiverType.TypeKind == 11) { return addressKind != Binder.AddressKind.Constrained; } return false; } private LocalDefinition EmitInstanceFieldAddress(BoundFieldAccess fieldAccess, Binder.AddressKind addressKind) { //IL_000f: 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) FieldSymbol fieldSymbol = fieldAccess.FieldSymbol; LocalDefinition result = EmitReceiverRef(fieldAccess.ReceiverOpt, ((int)fieldSymbol.RefKind != 0) ? ((addressKind != Binder.AddressKind.ReadOnlyStrict) ? Binder.AddressKind.ReadOnly : addressKind) : ((addressKind != Binder.AddressKind.Constrained) ? addressKind : Binder.AddressKind.Writeable)); _builder.EmitOpCode(((int)fieldSymbol.RefKind == 0) ? ILOpCode.Ldflda : ILOpCode.Ldfld); EmitSymbolToken(fieldSymbol, fieldAccess.Syntax); if (fieldSymbol.IsFixedSizeBuffer) { FieldSymbol fixedElementField = fieldSymbol.FixedImplementationType(_module).FixedElementField; if ((object)fixedElementField != null) { _builder.EmitOpCode(ILOpCode.Ldflda); EmitSymbolToken(fixedElementField, fieldAccess.Syntax); } } return result; } private void EmitArrayInitializers(ArrayTypeSymbol arrayType, BoundArrayInitialization inits) { ImmutableArray initializers = inits.Initializers; ArrayInitializerStyle arrayInitializerStyle = ShouldEmitBlockInitializer(arrayType.ElementType, initializers); if (arrayInitializerStyle == ArrayInitializerStyle.Element) { EmitElementInitializers(arrayType, initializers, includeConstants: true); return; } ImmutableArray rawData = GetRawData(initializers); _builder.EmitArrayBlockInitializer(rawData, inits.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); if (arrayInitializerStyle == ArrayInitializerStyle.Mixed) { EmitElementInitializers(arrayType, initializers, includeConstants: false); } } private void EmitElementInitializers(ArrayTypeSymbol arrayType, ImmutableArray inits, bool includeConstants) { if (!IsMultidimensionalInitializer(inits)) { EmitVectorElementInitializers(arrayType, inits, includeConstants); } else { EmitMultidimensionalElementInitializers(arrayType, inits, includeConstants); } } private void EmitVectorElementInitializers(ArrayTypeSymbol arrayType, ImmutableArray inits, bool includeConstants) { for (int i = 0; i < inits.Length; i++) { BoundExpression boundExpression = inits[i]; if (ShouldEmitInitExpression(includeConstants, boundExpression)) { _builder.EmitOpCode(ILOpCode.Dup); _builder.EmitIntConstant(i); EmitExpression(boundExpression, used: true); EmitVectorElementStore(arrayType, boundExpression.Syntax); } } } private static bool ShouldEmitInitExpression(bool includeConstants, BoundExpression init) { if (init.IsDefaultValue()) { return false; } if (!includeConstants) { return init.ConstantValueOpt == (ConstantValue)null; } return true; } private void EmitMultidimensionalElementInitializers(ArrayTypeSymbol arrayType, ImmutableArray inits, bool includeConstants) { ArrayBuilder val = new ArrayBuilder(); for (int i = 0; i < inits.Length; i++) { ArrayBuilderExtensions.Push(val, new IndexDesc(i, ((BoundArrayInitialization)inits[i]).Initializers)); EmitAllElementInitializersRecursive(arrayType, val, includeConstants); } } private void EmitAllElementInitializersRecursive(ArrayTypeSymbol arrayType, ArrayBuilder indices, bool includeConstants) { //IL_0076: 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) ImmutableArray initializers = ArrayBuilderExtensions.Peek(indices).Initializers; if (IsMultidimensionalInitializer(initializers)) { for (int i = 0; i < initializers.Length; i++) { ArrayBuilderExtensions.Push(indices, new IndexDesc(i, ((BoundArrayInitialization)initializers[i]).Initializers)); EmitAllElementInitializersRecursive(arrayType, indices, includeConstants); } } else { for (int j = 0; j < initializers.Length; j++) { BoundExpression boundExpression = initializers[j]; if (ShouldEmitInitExpression(includeConstants, boundExpression)) { _builder.EmitOpCode(ILOpCode.Dup); Enumerator enumerator = indices.GetEnumerator(); while (enumerator.MoveNext()) { IndexDesc current = enumerator.Current; _builder.EmitIntConstant(current.Index); } _builder.EmitIntConstant(j); BoundExpression expression = initializers[j]; EmitExpression(expression, used: true); EmitArrayElementStore(arrayType, boundExpression.Syntax); } } } ArrayBuilderExtensions.Pop(indices); } private static ConstantValue AsConstOrDefault(BoundExpression init) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) ConstantValue constantValueOpt = init.ConstantValueOpt; if (constantValueOpt != (ConstantValue)null) { return constantValueOpt; } return ConstantValue.Default(init.Type.EnumUnderlyingTypeOrSelf().SpecialType); } private ArrayInitializerStyle ShouldEmitBlockInitializer(TypeSymbol elementType, ImmutableArray inits) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (((CommonPEModuleBuilder)_module).IsEncDelta) { return ArrayInitializerStyle.Element; } if (elementType.IsEnumType()) { if (!EnableEnumArrayBlockInitialization) { return ArrayInitializerStyle.Element; } elementType = elementType.EnumUnderlyingTypeOrSelf(); } if (SpecialTypeExtensions.IsBlittable(elementType.SpecialType)) { if (((PEModuleBuilder)_module).GetInitArrayHelper() == null) { return ArrayInitializerStyle.Element; } int initCount = 0; int constInits = 0; InitializerCountRecursive(inits, ref initCount, ref constInits); if (initCount > 2) { if (initCount == constInits) { return ArrayInitializerStyle.Block; } int num = Math.Max(3, initCount / 3); if (constInits >= num) { return ArrayInitializerStyle.Mixed; } } } return ArrayInitializerStyle.Element; } private void InitializerCountRecursive(ImmutableArray inits, ref int initCount, ref int constInits) { if (inits.Length == 0) { return; } ImmutableArray.Enumerator enumerator = inits.GetEnumerator(); while (enumerator.MoveNext()) { BoundExpression current = enumerator.Current; if (current is BoundArrayInitialization boundArrayInitialization) { InitializerCountRecursive(boundArrayInitialization.Initializers, ref initCount, ref constInits); } else if (!current.IsDefaultValue()) { initCount++; if (current.ConstantValueOpt != (ConstantValue)null) { constInits++; } } } } private ImmutableArray GetRawData(ImmutableArray initializers) { BlobBuilder blobBuilder = new BlobBuilder(initializers.Length * 4); SerializeArrayRecursive(blobBuilder, initializers); return blobBuilder.ToImmutableArray(); } private void SerializeArrayRecursive(BlobBuilder bw, ImmutableArray inits) { if (inits.Length == 0) { return; } if (inits[0].Kind == BoundKind.ArrayInitialization) { ImmutableArray.Enumerator enumerator = inits.GetEnumerator(); while (enumerator.MoveNext()) { BoundExpression current = enumerator.Current; SerializeArrayRecursive(bw, ((BoundArrayInitialization)current).Initializers); } } else { ImmutableArray.Enumerator enumerator = inits.GetEnumerator(); while (enumerator.MoveNext()) { AsConstOrDefault(enumerator.Current).Serialize(bw); } } } private static bool IsMultidimensionalInitializer(ImmutableArray inits) { if (inits.Length != 0) { return inits[0].Kind == BoundKind.ArrayInitialization; } return false; } private bool TryEmitReadonlySpanAsBlobWrapper(NamedTypeSymbol spanType, BoundExpression wrappedExpression, bool used, BoundExpression inPlaceTarget, out bool avoidInPlace, BoundExpression? start = null, BoundExpression? length = null) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Invalid comparison between Unknown and I4 //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Invalid comparison between Unknown and I4 //IL_0294: Unknown result type (might be due to invalid IL or missing references) if (start == null != (length == null)) { throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/CodeGen/EmitArrayInitializer.cs", 438); } int num = -1; avoidInPlace = false; SpecialType val = (SpecialType)0; if (((CommonPEModuleBuilder)_module).IsEncDelta) { return false; } MethodSymbol methodSymbol = (MethodSymbol)Binder.GetWellKnownTypeMember(((PEModuleBuilder)_module).Compilation, (WellKnownMember)403, _diagnostics, null, wrappedExpression.Syntax, isOptional: true); if ((object)methodSymbol == null) { return false; } ImmutableArray data = default(ImmutableArray); ArrayTypeSymbol arrayTypeSymbol = null; TypeSymbol typeSymbol = null; if (wrappedExpression is BoundArrayCreation boundArrayCreation) { arrayTypeSymbol = (ArrayTypeSymbol)boundArrayCreation.Type; typeSymbol = arrayTypeSymbol.ElementType; val = typeSymbol.EnumUnderlyingTypeOrSelf().SpecialType; if (!IsTypeAllowedInBlobWrapper(val)) { return false; } num = TryGetRawDataForArrayInit(boundArrayCreation.InitializerOpt, out data); } if (num < 0) { return false; } int num2; if (start != null) { ConstantValue? constantValueOpt = start.ConstantValueOpt; if (constantValueOpt == null || !constantValueOpt.IsDefaultValue || (int)start.ConstantValueOpt.Discriminator != 6) { return false; } ConstantValue? constantValueOpt2 = length.ConstantValueOpt; if (constantValueOpt2 == null || (int)constantValueOpt2.Discriminator != 6) { return false; } num2 = length.ConstantValueOpt.Int32Value; if (num2 > num || num2 < 0) { return false; } } else { num2 = num; } if (inPlaceTarget == null && !used) { return true; } if (num == 0) { if (inPlaceTarget != null) { EmitAddress(inPlaceTarget, Binder.AddressKind.Writeable); _builder.EmitOpCode(ILOpCode.Initobj); EmitSymbolToken(spanType, wrappedExpression.Syntax); if (used) { EmitExpression(inPlaceTarget, used: true); } } else { EmitDefaultValue(spanType, used, wrappedExpression.Syntax); } return true; } if (IsPeVerifyCompatEnabled()) { return false; } if (SpecialTypeExtensions.SizeInBytes(val) == 1) { if (inPlaceTarget != null) { EmitAddress(inPlaceTarget, Binder.AddressKind.Writeable); } IFieldReference fieldForData = _builder.module.GetFieldForData(data, (ushort)1, wrappedExpression.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); _builder.EmitOpCode(ILOpCode.Ldsflda); _builder.EmitToken((IReference)(object)fieldForData, wrappedExpression.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag, (RawTokenEncoding)0); _builder.EmitIntConstant(num2); if (inPlaceTarget != null) { _builder.EmitOpCode(ILOpCode.Call, -3); } else { _builder.EmitOpCode(ILOpCode.Newobj, -1); } EmitSymbolToken(methodSymbol.AsMember(spanType), wrappedExpression.Syntax, null); if (inPlaceTarget != null && used) { EmitExpression(inPlaceTarget, used: true); } return true; } if (num2 != num) { return false; } if (inPlaceTarget != null) { avoidInPlace = true; return false; } MethodSymbol methodSymbol2 = (MethodSymbol)Binder.GetWellKnownTypeMember(((PEModuleBuilder)_module).Compilation, (WellKnownMember)123, _diagnostics, null, wrappedExpression.Syntax, isOptional: true); if ((object)methodSymbol2 != null) { IFieldReference fieldForData2 = _builder.module.GetFieldForData(data, (ushort)SpecialTypeExtensions.SizeInBytes(val), wrappedExpression.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); _builder.EmitOpCode(ILOpCode.Ldtoken); _builder.EmitToken((IReference)(object)fieldForData2, wrappedExpression.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag, (RawTokenEncoding)0); _builder.EmitOpCode(ILOpCode.Call, 0); EmitSymbolToken(methodSymbol2.Construct(typeSymbol), wrappedExpression.Syntax, null); return true; } MethodSymbol methodSymbol3 = (MethodSymbol)Binder.GetWellKnownTypeMember(((PEModuleBuilder)_module).Compilation, (WellKnownMember)404, _diagnostics, null, wrappedExpression.Syntax, isOptional: true); if ((object)methodSymbol3 == null) { return false; } arrayTypeSymbol = arrayTypeSymbol.WithElementType(TypeWithAnnotations.Create(typeSymbol.EnumUnderlyingTypeOrSelf())); IFieldReference arrayCachingFieldForData = _builder.module.GetArrayCachingFieldForData(data, _module.Translate(arrayTypeSymbol), wrappedExpression.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); object obj = new object(); _builder.EmitOpCode(ILOpCode.Ldsfld); _builder.EmitToken((IReference)(object)arrayCachingFieldForData, wrappedExpression.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag, (RawTokenEncoding)0); _builder.EmitOpCode(ILOpCode.Dup); _builder.EmitBranch(ILOpCode.Brtrue, obj, ILOpCode.Nop); _builder.EmitOpCode(ILOpCode.Pop); _builder.EmitIntConstant(num); _builder.EmitOpCode(ILOpCode.Newarr); EmitSymbolToken(arrayTypeSymbol.ElementType, wrappedExpression.Syntax); _builder.EmitArrayBlockInitializer(data, wrappedExpression.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); _builder.EmitOpCode(ILOpCode.Dup); _builder.EmitOpCode(ILOpCode.Stsfld); _builder.EmitToken((IReference)(object)arrayCachingFieldForData, wrappedExpression.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag, (RawTokenEncoding)0); _builder.MarkLabel(obj); _builder.EmitOpCode(ILOpCode.Newobj, 0); EmitSymbolToken(methodSymbol3.AsMember(spanType), wrappedExpression.Syntax, null); return true; } internal static bool IsTypeAllowedInBlobWrapper(SpecialType type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Invalid comparison between Unknown and I4 //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 if (type - 7 <= 9 || type - 18 <= 1) { return true; } return false; } private int TryGetRawDataForArrayInit(BoundArrayInitialization initializer, out ImmutableArray data) { data = default(ImmutableArray); if (initializer == null) { return -1; } ImmutableArray initializers = initializer.Initializers; if (initializers.Any((BoundExpression init) => init.ConstantValueOpt == (ConstantValue)null)) { return -1; } int length = initializers.Length; if (length == 0) { data = ImmutableArray.Empty; return 0; } BlobBuilder blobBuilder = new BlobBuilder(initializers.Length * 4); ImmutableArray.Enumerator enumerator = initializer.Initializers.GetEnumerator(); while (enumerator.MoveNext()) { enumerator.Current.ConstantValueOpt.Serialize(blobBuilder); } data = blobBuilder.ToImmutableArray(); return length; } private static bool IsNumeric(TypeSymbol type) { //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: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected I4, but got Unknown PrimitiveTypeCode primitiveTypeCode = type.PrimitiveTypeCode; switch (primitiveTypeCode - 1) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 11: case 12: case 13: case 14: return true; case 7: case 15: return type.IsNativeIntegerType; default: return false; } } private void EmitConversionExpression(BoundConversion conversion, bool used) { switch (conversion.ConversionKind) { case ConversionKind.MethodGroup: throw ExceptionUtilities.UnexpectedValue((object)conversion.ConversionKind); case ConversionKind.ImplicitNullToPointer: _builder.EmitIntConstant(0); _builder.EmitOpCode(ILOpCode.Conv_u); EmitPopIfUnused(used); return; } BoundExpression operand = conversion.Operand; if (!used && !conversion.ConversionHasSideEffects()) { EmitExpression(operand, used: false); return; } EmitExpression(operand, used: true); EmitConversion(conversion); EmitPopIfUnused(used); } private void EmitReadOnlySpanFromArrayExpression(BoundReadOnlySpanFromArray expression, bool used) { BoundExpression operand = expression.Operand; NamedTypeSymbol spanType = (NamedTypeSymbol)expression.Type; if (!TryEmitReadonlySpanAsBlobWrapper(spanType, operand, used, null, out var _)) { EmitExpression(operand, used); if (used) { _builder.EmitOpCode(ILOpCode.Call, 0); EmitSymbolToken(expression.ConversionMethod, expression.Syntax, null); } } } private void EmitConversion(BoundConversion conversion) { //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) switch (conversion.ConversionKind) { case ConversionKind.Identity: EmitIdentityConversion(conversion); break; case ConversionKind.ImplicitNumeric: case ConversionKind.ExplicitNumeric: EmitNumericConversion(conversion); break; case ConversionKind.ImplicitReference: case ConversionKind.Boxing: EmitImplicitReferenceConversion(conversion); break; case ConversionKind.ExplicitReference: case ConversionKind.Unboxing: EmitExplicitReferenceConversion(conversion); break; case ConversionKind.ImplicitEnumeration: case ConversionKind.ExplicitEnumeration: EmitEnumConversion(conversion); break; case ConversionKind.ImplicitThrow: case ConversionKind.ImplicitTupleLiteral: case ConversionKind.ImplicitTuple: case ConversionKind.ExplicitTupleLiteral: case ConversionKind.ExplicitTuple: case ConversionKind.ImplicitDynamic: case ConversionKind.ExplicitDynamic: case ConversionKind.ImplicitUserDefined: case ConversionKind.AnonymousFunction: case ConversionKind.MethodGroup: case ConversionKind.ExplicitUserDefined: throw ExceptionUtilities.UnexpectedValue((object)conversion.ConversionKind); case ConversionKind.ImplicitPointerToVoid: case ConversionKind.ImplicitPointer: case ConversionKind.ExplicitPointerToPointer: break; case ConversionKind.ExplicitIntegerToPointer: case ConversionKind.ExplicitPointerToInteger: { PrimitiveTypeCode primitiveTypeCode = conversion.Operand.Type.PrimitiveTypeCode; PrimitiveTypeCode primitiveTypeCode2 = conversion.Type.PrimitiveTypeCode; _builder.EmitNumericConversion(primitiveTypeCode, primitiveTypeCode2, conversion.Checked); break; } case ConversionKind.PinnedObjectToPointer: _builder.EmitOpCode(ILOpCode.Conv_u); break; case ConversionKind.ImplicitNullToPointer: throw ExceptionUtilities.UnexpectedValue((object)conversion.ConversionKind); default: throw ExceptionUtilities.UnexpectedValue((object)conversion.ConversionKind); } } private void EmitIdentityConversion(BoundConversion conversion) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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) //IL_0018: Invalid comparison between Unknown and I4 if (conversion.ExplicitCastInCode) { PrimitiveTypeCode primitiveTypeCode = conversion.Type.PrimitiveTypeCode; if (primitiveTypeCode - 3 <= 1 && conversion.Operand.ConstantValueOpt == (ConstantValue)null) { EmitNumericConversion(conversion); } } } private void EmitNumericConversion(BoundConversion conversion) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) PrimitiveTypeCode primitiveTypeCode = conversion.Operand.Type.PrimitiveTypeCode; PrimitiveTypeCode primitiveTypeCode2 = conversion.Type.PrimitiveTypeCode; _builder.EmitNumericConversion(primitiveTypeCode, primitiveTypeCode2, conversion.Checked); } private void EmitImplicitReferenceConversion(BoundConversion conversion) { if (!conversion.Operand.Type.IsVerifierReference()) { EmitBox(conversion.Operand.Type, conversion.Operand.Syntax); } TypeSymbol type = conversion.Type; if (!type.IsVerifierReference()) { _builder.EmitOpCode(ILOpCode.Unbox_any); EmitSymbolToken(conversion.Type, conversion.Syntax); } else if (type.IsArray()) { EmitStaticCast(conversion.Type, conversion.Syntax); } } private void EmitExplicitReferenceConversion(BoundConversion conversion) { if (!conversion.Operand.Type.IsVerifierReference()) { EmitBox(conversion.Operand.Type, conversion.Operand.Syntax); } if (conversion.Type.IsVerifierReference()) { _builder.EmitOpCode(ILOpCode.Castclass); EmitSymbolToken(conversion.Type, conversion.Syntax); } else { _builder.EmitOpCode(ILOpCode.Unbox_any); EmitSymbolToken(conversion.Type, conversion.Syntax); } } private void EmitEnumConversion(BoundConversion conversion) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) TypeSymbol typeSymbol = conversion.Operand.Type; if (typeSymbol.IsEnumType()) { typeSymbol = ((NamedTypeSymbol)typeSymbol).EnumUnderlyingType; } PrimitiveTypeCode primitiveTypeCode = typeSymbol.PrimitiveTypeCode; TypeSymbol typeSymbol2 = conversion.Type; if (typeSymbol2.IsEnumType()) { typeSymbol2 = ((NamedTypeSymbol)typeSymbol2).EnumUnderlyingType; } PrimitiveTypeCode primitiveTypeCode2 = typeSymbol2.PrimitiveTypeCode; _builder.EmitNumericConversion(primitiveTypeCode, primitiveTypeCode2, conversion.Checked); } private void EmitDelegateCreation(BoundExpression node, BoundExpression receiver, bool isExtensionMethod, MethodSymbol method, TypeSymbol delegateType, bool used) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Invalid comparison between Unknown and I4 bool flag = receiver == null || (!isExtensionMethod && method.IsStatic); if (!used) { if (!flag) { EmitExpression(receiver, used: false); } return; } if (flag) { _builder.EmitNullConstant(); if (method.IsAbstract || method.IsVirtual) { if (receiver is BoundTypeExpression boundTypeExpression) { TypeSymbol type = boundTypeExpression.Type; if ((object)type != null && (int)type.TypeKind == 11) { _builder.EmitOpCode(ILOpCode.Constrained); EmitSymbolToken(receiver.Type, receiver.Syntax); goto IL_00bd; } } throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/CodeGen/EmitConversion.cs", 333); } } else { EmitExpression(receiver, used: true); if (!receiver.Type.IsVerifierReference()) { EmitBox(receiver.Type, receiver.Syntax); } } goto IL_00bd; IL_00bd: if (!method.IsStatic && method.IsMetadataVirtual() && !method.ContainingType.IsDelegateType() && !receiver.SuppressVirtualCalls) { _builder.EmitOpCode(ILOpCode.Dup); _builder.EmitOpCode(ILOpCode.Ldvirtftn); method = method.GetConstructedLeastOverriddenMethod(_method.ContainingType, requireSameReturnType: true); } else { _builder.EmitOpCode(ILOpCode.Ldftn); } EmitSymbolToken(method, node.Syntax, null); _builder.EmitOpCode(ILOpCode.Newobj, -1); MethodSymbol methodSymbol = DelegateConstructor(node.Syntax, delegateType); if ((object)methodSymbol != null) { EmitSymbolToken(methodSymbol, node.Syntax, null); } } private MethodSymbol DelegateConstructor(SyntaxNode syntax, TypeSymbol delegateType) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Invalid comparison between Unknown and I4 //IL_0059: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Invalid comparison between Unknown and I4 //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Invalid comparison between Unknown and I4 ImmutableArray.Enumerator enumerator = delegateType.GetMembers(".ctor").GetEnumerator(); while (enumerator.MoveNext()) { if (enumerator.Current is MethodSymbol { Parameters: { Length: 2 } parameters } methodSymbol && (int)parameters[0].Type.SpecialType == 1) { SpecialType specialType = parameters[1].Type.SpecialType; if ((int)specialType == 21 || (int)specialType == 22) { return methodSymbol; } } } _diagnostics.Add(ErrorCode.ERR_BadDelegateConstructor, syntax.Location, delegateType); return null; } private void EmitExpression(BoundExpression expression, bool used) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 if (expression == null) { return; } ConstantValue constantValueOpt = expression.ConstantValueOpt; if (constantValueOpt != (ConstantValue)null) { if (!used) { return; } if ((object)expression.Type == null || ((int)expression.Type.SpecialType != 17 && !expression.Type.IsNullableType())) { EmitConstantExpression(expression.Type, constantValueOpt, used, expression.Syntax); return; } } _recursionDepth++; if (_recursionDepth > 1) { StackGuard.EnsureSufficientExecutionStack(_recursionDepth); EmitExpressionCore(expression, used); } else { EmitExpressionCoreWithStackGuard(expression, used); } _recursionDepth--; } private void EmitExpressionCoreWithStackGuard(BoundExpression expression, bool used) { try { EmitExpressionCore(expression, used); } catch (InsufficientExecutionStackException) { _diagnostics.Add(ErrorCode.ERR_InsufficientStack, BoundTreeVisitor.CancelledByStackGuardException.GetTooLongOrComplexExpressionErrorLocation(expression)); throw new EmitCancelledException(); } } private void EmitExpressionCore(BoundExpression expression, bool used) { switch (expression.Kind) { case BoundKind.AssignmentOperator: EmitAssignmentExpression((BoundAssignmentOperator)expression, used ? UseKind.UsedAsValue : UseKind.Unused); break; case BoundKind.Call: EmitCallExpression((BoundCall)expression, used ? UseKind.UsedAsValue : UseKind.Unused); break; case BoundKind.ObjectCreationExpression: EmitObjectCreationExpression((BoundObjectCreationExpression)expression, used); break; case BoundKind.DelegateCreationExpression: EmitDelegateCreationExpression((BoundDelegateCreationExpression)expression, used); break; case BoundKind.ArrayCreation: EmitArrayCreationExpression((BoundArrayCreation)expression, used); break; case BoundKind.ConvertedStackAllocExpression: EmitConvertedStackAllocExpression((BoundConvertedStackAllocExpression)expression, used); break; case BoundKind.ReadOnlySpanFromArray: EmitReadOnlySpanFromArrayExpression((BoundReadOnlySpanFromArray)expression, used); break; case BoundKind.Conversion: EmitConversionExpression((BoundConversion)expression, used); break; case BoundKind.Local: EmitLocalLoad((BoundLocal)expression, used); break; case BoundKind.Dup: EmitDupExpression((BoundDup)expression, used); break; case BoundKind.PassByCopy: EmitExpression(((BoundPassByCopy)expression).Expression, used); break; case BoundKind.Parameter: if (used) { EmitParameterLoad((BoundParameter)expression); } break; case BoundKind.FieldAccess: EmitFieldLoad((BoundFieldAccess)expression, used); break; case BoundKind.ArrayAccess: EmitArrayElementLoad((BoundArrayAccess)expression, used); break; case BoundKind.ArrayLength: EmitArrayLength((BoundArrayLength)expression, used); break; case BoundKind.ThisReference: if (used) { EmitThisReferenceExpression((BoundThisReference)expression); } break; case BoundKind.PreviousSubmissionReference: throw ExceptionUtilities.UnexpectedValue((object)expression.Kind); case BoundKind.BaseReference: if (used) { NamedTypeSymbol containingType = _method.ContainingType; _builder.EmitOpCode(ILOpCode.Ldarg_0); if (containingType.IsValueType) { EmitLoadIndirect(containingType, expression.Syntax); EmitBox(containingType, expression.Syntax); } } break; case BoundKind.Sequence: EmitSequenceExpression((BoundSequence)expression, used); break; case BoundKind.SequencePointExpression: EmitSequencePointExpression((BoundSequencePointExpression)expression, used); break; case BoundKind.UnaryOperator: EmitUnaryOperatorExpression((BoundUnaryOperator)expression, used); break; case BoundKind.BinaryOperator: EmitBinaryOperatorExpression((BoundBinaryOperator)expression, used); break; case BoundKind.NullCoalescingOperator: EmitNullCoalescingOperator((BoundNullCoalescingOperator)expression, used); break; case BoundKind.IsOperator: EmitIsExpression((BoundIsOperator)expression, used, omitBooleanConversion: false); break; case BoundKind.AsOperator: EmitAsExpression((BoundAsOperator)expression, used); break; case BoundKind.DefaultExpression: EmitDefaultExpression((BoundDefaultExpression)expression, used); break; case BoundKind.TypeOfOperator: if (used) { EmitTypeOfExpression((BoundTypeOfOperator)expression); } break; case BoundKind.SizeOfOperator: if (used) { EmitSizeOfExpression((BoundSizeOfOperator)expression); } break; case BoundKind.ModuleVersionId: EmitModuleVersionIdLoad((BoundModuleVersionId)expression); break; case BoundKind.ModuleVersionIdString: EmitModuleVersionIdStringLoad(); break; case BoundKind.InstrumentationPayloadRoot: EmitInstrumentationPayloadRootLoad((BoundInstrumentationPayloadRoot)expression); break; case BoundKind.MethodDefIndex: EmitMethodDefIndexExpression((BoundMethodDefIndex)expression); break; case BoundKind.MaximumMethodDefIndex: EmitMaximumMethodDefIndexExpression((BoundMaximumMethodDefIndex)expression); break; case BoundKind.SourceDocumentIndex: EmitSourceDocumentIndex((BoundSourceDocumentIndex)expression); break; case BoundKind.LocalId: EmitLocalIdExpression((BoundLocalId)expression); break; case BoundKind.ParameterId: EmitParameterIdExpression((BoundParameterId)expression); break; case BoundKind.MethodInfo: if (used) { EmitMethodInfoExpression((BoundMethodInfo)expression); } break; case BoundKind.FieldInfo: if (used) { EmitFieldInfoExpression((BoundFieldInfo)expression); } break; case BoundKind.ConditionalOperator: EmitConditionalOperator((BoundConditionalOperator)expression, used); break; case BoundKind.AddressOfOperator: EmitAddressOfExpression((BoundAddressOfOperator)expression, used); break; case BoundKind.PointerIndirectionOperator: EmitPointerIndirectionOperator((BoundPointerIndirectionOperator)expression, used); break; case BoundKind.ArgList: EmitArgList(used); break; case BoundKind.ArgListOperator: EmitArgListOperator((BoundArgListOperator)expression); break; case BoundKind.RefTypeOperator: EmitRefTypeOperator((BoundRefTypeOperator)expression, used); break; case BoundKind.MakeRefOperator: EmitMakeRefOperator((BoundMakeRefOperator)expression, used); break; case BoundKind.RefValueOperator: EmitRefValueOperator((BoundRefValueOperator)expression, used); break; case BoundKind.LoweredConditionalAccess: EmitLoweredConditionalAccessExpression((BoundLoweredConditionalAccess)expression, used); break; case BoundKind.ConditionalReceiver: EmitConditionalReceiver((BoundConditionalReceiver)expression, used); break; case BoundKind.ComplexConditionalReceiver: EmitComplexConditionalReceiver((BoundComplexConditionalReceiver)expression, used); break; case BoundKind.PseudoVariable: EmitPseudoVariableValue((BoundPseudoVariable)expression, used); break; case BoundKind.ThrowExpression: EmitThrowExpression((BoundThrowExpression)expression, used); break; case BoundKind.FunctionPointerInvocation: EmitCalli((BoundFunctionPointerInvocation)expression, used ? UseKind.UsedAsValue : UseKind.Unused); break; case BoundKind.FunctionPointerLoad: EmitLoadFunction((BoundFunctionPointerLoad)expression, used); break; default: throw ExceptionUtilities.UnexpectedValue((object)expression.Kind); } } private void EmitThrowExpression(BoundThrowExpression node, bool used) { EmitThrow(node.Expression); EmitDefaultValue(node.Type, used, node.Syntax); } private void EmitComplexConditionalReceiver(BoundComplexConditionalReceiver expression, bool used) { TypeSymbol type = expression.Type; object obj = new object(); object obj2 = new object(); EmitInitObj(type, used: true, expression.Syntax); EmitBox(type, expression.Syntax); _builder.EmitBranch(ILOpCode.Brtrue, obj, ILOpCode.Nop); EmitExpression(expression.ReferenceTypeReceiver, used); _builder.EmitBranch(ILOpCode.Br, obj2, ILOpCode.Nop); if (used) { _builder.AdjustStack(-1); } _builder.MarkLabel(obj); EmitExpression(expression.ValueTypeReceiver, used); _builder.MarkLabel(obj2); } private void EmitLoweredConditionalAccessExpression(BoundLoweredConditionalAccess expression, bool used) { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Invalid comparison between Unknown and I4 BoundExpression receiver = expression.Receiver; TypeSymbol type = receiver.Type; LocalDefinition val = null; ConstantValue? constantValueOpt = receiver.ConstantValueOpt; if (constantValueOpt != null && !constantValueOpt.IsNull) { val = EmitReceiverRef(receiver, Binder.AddressKind.ReadOnly); EmitExpression(expression.WhenNotNull, used); if (val != null) { FreeTemp(val); } return; } object obj = new object(); object obj2 = new object(); LocalDefinition val2 = null; bool flag = !type.IsReferenceType && !type.IsValueType; bool flag2 = (expression.ForceCopyOfNullableValueType && flag && ((TypeParameterSymbol)type).EffectiveInterfacesNoUseSiteDiagnostics.IsEmpty) || LocalRewriter.CanChangeValueBetweenReads(receiver, localsMayBeAssignedOrCaptured: false) || (type.IsReferenceType && (int)type.TypeKind == 11) || (receiver.Kind == BoundKind.Local && IsStackLocal(((BoundLocal)receiver).LocalSymbol)) || (flag && IsConditionalConstrainedCallThatMustUseTempForReferenceTypeReceiverWalker.Analyze(expression)); if (flag2) { if (flag) { val = EmitReceiverRef(receiver, Binder.AddressKind.Constrained); if (val == null) { EmitDefaultValue(type, used: true, receiver.Syntax); EmitBox(type, receiver.Syntax); _builder.EmitBranch(ILOpCode.Brtrue, obj, ILOpCode.Nop); EmitLoadIndirect(type, receiver.Syntax); val2 = AllocateTemp(type, receiver.Syntax, (LocalSlotConstraints)0); _builder.EmitLocalStore(val2); _builder.EmitLocalAddress(val2); _builder.EmitLocalLoad(val2); EmitBox(type, receiver.Syntax); } else { _builder.EmitOpCode(ILOpCode.Dup); EmitLoadIndirect(type, receiver.Syntax); EmitBox(type, receiver.Syntax); } } else { Binder.AddressKind addressKind = Binder.AddressKind.ReadOnly; val = EmitReceiverRef(receiver, addressKind); _builder.EmitOpCode(ILOpCode.Dup); } } else { val = EmitReceiverRef(receiver, Binder.AddressKind.ReadOnly); } MethodSymbol hasValueMethodOpt = expression.HasValueMethodOpt; if (hasValueMethodOpt != null) { _builder.EmitOpCode(ILOpCode.Call, 0); EmitSymbolToken(hasValueMethodOpt, expression.Syntax, null); } _builder.EmitBranch(ILOpCode.Brtrue, obj, ILOpCode.Nop); if (val != null && !flag2) { FreeTemp(val); val = null; } if (flag2) { _builder.EmitOpCode(ILOpCode.Pop); } BoundExpression whenNullOpt = expression.WhenNullOpt; if (whenNullOpt == null) { EmitDefaultValue(expression.Type, used, expression.Syntax); } else { EmitExpression(whenNullOpt, used); } _builder.EmitBranch(ILOpCode.Br, obj2, ILOpCode.Nop); if (flag2) { _builder.AdjustStack(1); } if (used) { _builder.AdjustStack(-1); } _builder.MarkLabel(obj); if (!flag2) { val = EmitReceiverRef(receiver, Binder.AddressKind.Constrained); } EmitExpression(expression.WhenNotNull, used); _builder.MarkLabel(obj2); if (val2 != null) { FreeTemp(val2); } if (val != null) { FreeTemp(val); } } private void EmitConditionalReceiver(BoundConditionalReceiver expression, bool used) { if (!expression.Type.IsReferenceType) { EmitLoadIndirect(expression.Type, expression.Syntax); } EmitPopIfUnused(used); } private void EmitRefValueOperator(BoundRefValueOperator expression, bool used) { EmitRefValueAddress(expression); EmitLoadIndirect(expression.Type, expression.Syntax); EmitPopIfUnused(used); } private void EmitMakeRefOperator(BoundMakeRefOperator expression, bool used) { EmitAddress(expression.Operand, Binder.AddressKind.Writeable); _builder.EmitOpCode(ILOpCode.Mkrefany); EmitSymbolToken(expression.Operand.Type, expression.Operand.Syntax); EmitPopIfUnused(used); } private void EmitRefTypeOperator(BoundRefTypeOperator expression, bool used) { EmitExpression(expression.Operand, used: true); _builder.EmitOpCode(ILOpCode.Refanytype); _builder.EmitOpCode(ILOpCode.Call, 0); MethodSymbol getTypeFromHandle = expression.GetTypeFromHandle; EmitSymbolToken(getTypeFromHandle, expression.Syntax, null); EmitPopIfUnused(used); } private void EmitArgList(bool used) { _builder.EmitOpCode(ILOpCode.Arglist); EmitPopIfUnused(used); } private void EmitArgListOperator(BoundArgListOperator expression) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < expression.Arguments.Length; i++) { BoundExpression argument = expression.Arguments[i]; RefKind refKind = (RefKind)((!expression.ArgumentRefKindsOpt.IsDefaultOrEmpty) ? ((int)expression.ArgumentRefKindsOpt[i]) : 0); EmitArgument(argument, refKind); } } private void EmitArgument(BoundExpression argument, RefKind refKind) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Invalid comparison between Unknown and I4 //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 if ((int)refKind != 0) { if ((int)refKind == 3) { LocalDefinition temp = EmitAddress(argument, Binder.AddressKind.ReadOnly); AddExpressionTemp(temp); return; } LocalDefinition val = EmitAddress(argument, ((int)refKind == 5) ? Binder.AddressKind.ReadOnlyStrict : Binder.AddressKind.Writeable); if (val != null) { AddExpressionTemp(val); } } else { EmitExpression(argument, used: true); } } private void EmitAddressOfExpression(BoundAddressOfOperator expression, bool used) { EmitAddress(expression.Operand, Binder.AddressKind.ReadOnlyStrict); if (used && !expression.IsManaged) { _builder.EmitOpCode(ILOpCode.Conv_u); } EmitPopIfUnused(used); } private void EmitPointerIndirectionOperator(BoundPointerIndirectionOperator expression, bool used) { EmitExpression(expression.Operand, used: true); if (!expression.RefersToLocation) { EmitLoadIndirect(expression.Type, expression.Syntax); } EmitPopIfUnused(used); } private void EmitDupExpression(BoundDup expression, bool used) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if ((int)expression.RefKind == 0) { if (used) { _builder.EmitOpCode(ILOpCode.Dup); } } else { _builder.EmitOpCode(ILOpCode.Dup); EmitLoadIndirect(expression.Type, expression.Syntax); EmitPopIfUnused(used); } } private void EmitDelegateCreationExpression(BoundDelegateCreationExpression expression, bool used) { BoundExpression boundExpression = ((expression.Argument is BoundMethodGroup boundMethodGroup) ? boundMethodGroup.ReceiverOpt : expression.Argument); MethodSymbol method = expression.MethodOpt ?? boundExpression.Type.DelegateInvokeMethod(); EmitDelegateCreation(expression, boundExpression, expression.IsExtensionMethod, method, expression.Type, used); } private void EmitThisReferenceExpression(BoundThisReference thisRef) { TypeSymbol type = thisRef.Type; _builder.EmitOpCode(ILOpCode.Ldarg_0); if (type.IsValueType) { EmitLoadIndirect(type, thisRef.Syntax); } } private void EmitPseudoVariableValue(BoundPseudoVariable expression, bool used) { EmitExpression(expression.EmitExpressions.GetValue(expression, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag), used); } private void EmitSequencePointExpression(BoundSequencePointExpression node, bool used) { EmitSequencePoint(node); EmitExpression(node.Expression, used: true); EmitPopIfUnused(used); } private void EmitSequencePoint(BoundSequencePointExpression node) { SyntaxNode syntax = node.Syntax; if (_emitPdbSequencePoints) { if (syntax == null) { EmitHiddenSequencePoint(); } else { EmitSequencePoint(syntax); } } } private void EmitSequenceExpression(BoundSequence sequence, bool used) { DefineLocals(sequence); EmitSideEffects(sequence); if (sequence.Value.Kind != BoundKind.TypeExpression) { EmitExpression(sequence.Value, used); } FreeLocals(sequence); } private void DefineLocals(BoundSequence sequence) { if (!sequence.Locals.IsEmpty) { _builder.OpenLocalScope((ScopeType)0, (ITypeReference)null); ImmutableArray.Enumerator enumerator = sequence.Locals.GetEnumerator(); while (enumerator.MoveNext()) { LocalSymbol current = enumerator.Current; DefineLocal(current, sequence.Syntax); } } } private void FreeLocals(BoundSequence sequence) { if (!sequence.Locals.IsEmpty) { _builder.CloseLocalScope(); ImmutableArray.Enumerator enumerator = sequence.Locals.GetEnumerator(); while (enumerator.MoveNext()) { LocalSymbol current = enumerator.Current; FreeLocal(current); } } } private void DefineAndRecordLocals(BoundSequence sequence) { if (!sequence.Locals.IsEmpty) { _builder.OpenLocalScope((ScopeType)0, (ITypeReference)null); ImmutableArray.Enumerator enumerator = sequence.Locals.GetEnumerator(); while (enumerator.MoveNext()) { LocalSymbol current = enumerator.Current; LocalDefinition temp = DefineLocal(current, sequence.Syntax); AddExpressionTemp(temp); } } } private void CloseScopeAndKeepLocals(BoundSequence sequence) { if (!sequence.Locals.IsEmpty) { _builder.CloseLocalScope(); } } private void EmitSideEffects(BoundSequence sequence) { ImmutableArray sideEffects = sequence.SideEffects; if (!sideEffects.IsDefaultOrEmpty) { ImmutableArray.Enumerator enumerator = sideEffects.GetEnumerator(); while (enumerator.MoveNext()) { BoundExpression current = enumerator.Current; EmitExpression(current, used: false); } } } private void EmitArguments(ImmutableArray arguments, ImmutableArray parameters, ImmutableArray argRefKindsOpt) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < arguments.Length; i++) { RefKind argumentRefKind = GetArgumentRefKind(arguments, parameters, argRefKindsOpt, i); EmitArgument(arguments[i], argumentRefKind); } } internal static RefKind GetArgumentRefKind(ImmutableArray arguments, ImmutableArray parameters, ImmutableArray argRefKindsOpt, int i) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0038: Invalid comparison between Unknown and I4 //IL_003e: 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) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (i < parameters.Length) { if (!argRefKindsOpt.IsDefault && i < argRefKindsOpt.Length) { return argRefKindsOpt[i]; } RefKind refKind = parameters[i].RefKind; return ((int)refKind != 4) ? refKind : ((RefKind)3); } return (RefKind)0; } private void EmitArrayElementLoad(BoundArrayAccess arrayAccess, bool used) { //IL_004f: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected I4, but got Unknown //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Invalid comparison between Unknown and I4 EmitExpression(arrayAccess.Expression, used: true); EmitArrayIndices(arrayAccess.Indices); if (((ArrayTypeSymbol)arrayAccess.Expression.Type).IsSZArray) { TypeSymbol typeSymbol = arrayAccess.Type; if (typeSymbol.IsEnumType()) { typeSymbol = ((NamedTypeSymbol)typeSymbol).EnumUnderlyingType; } PrimitiveTypeCode primitiveTypeCode = typeSymbol.PrimitiveTypeCode; switch ((int)primitiveTypeCode) { case 2: _builder.EmitOpCode(ILOpCode.Ldelem_i1); break; case 0: case 12: _builder.EmitOpCode(ILOpCode.Ldelem_u1); break; case 5: _builder.EmitOpCode(ILOpCode.Ldelem_i2); break; case 1: case 13: _builder.EmitOpCode(ILOpCode.Ldelem_u2); break; case 6: _builder.EmitOpCode(ILOpCode.Ldelem_i4); break; case 14: _builder.EmitOpCode(ILOpCode.Ldelem_u4); break; case 7: case 15: _builder.EmitOpCode(ILOpCode.Ldelem_i8); break; case 8: case 9: case 16: case 19: _builder.EmitOpCode(ILOpCode.Ldelem_i); break; case 3: _builder.EmitOpCode(ILOpCode.Ldelem_r4); break; case 4: _builder.EmitOpCode(ILOpCode.Ldelem_r8); break; default: if (typeSymbol.IsVerifierReference()) { _builder.EmitOpCode(ILOpCode.Ldelem_ref); break; } if (used) { _builder.EmitOpCode(ILOpCode.Ldelem); } else { if ((int)typeSymbol.TypeKind == 11) { _builder.EmitOpCode(ILOpCode.Readonly); } _builder.EmitOpCode(ILOpCode.Ldelema); } EmitSymbolToken(typeSymbol, arrayAccess.Syntax); break; } } else { _builder.EmitArrayElementLoad(_module.Translate((ArrayTypeSymbol)arrayAccess.Expression.Type), arrayAccess.Expression.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); } EmitPopIfUnused(used); } private void EmitFieldLoad(BoundFieldAccess fieldAccess, bool used) { //IL_0054: 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) FieldSymbol fieldSymbol = fieldAccess.FieldSymbol; if (!used) { if (fieldSymbol.IsCapturedFrame) { return; } if (!fieldSymbol.IsVolatile && !fieldSymbol.IsStatic && fieldAccess.ReceiverOpt.Type.IsVerifierValue() && (int)fieldSymbol.RefKind == 0) { EmitExpression(fieldAccess.ReceiverOpt, used: false); return; } } EmitFieldLoadNoIndirection(fieldAccess, used); if ((int)fieldSymbol.RefKind != 0) { EmitLoadIndirect(fieldSymbol.Type, fieldAccess.Syntax); } EmitPopIfUnused(used); } private void EmitFieldLoadNoIndirection(BoundFieldAccess fieldAccess, bool used) { FieldSymbol fieldSymbol = fieldAccess.FieldSymbol; if (fieldSymbol.IsStatic) { if (fieldSymbol.IsVolatile) { _builder.EmitOpCode(ILOpCode.Volatile); } _builder.EmitOpCode(ILOpCode.Ldsfld); EmitSymbolToken(fieldSymbol, fieldAccess.Syntax); return; } BoundExpression receiverOpt = fieldAccess.ReceiverOpt; TypeSymbol type = fieldSymbol.Type; if (type.IsValueType && (object)type == receiverOpt.Type) { EmitExpression(receiverOpt, used); return; } LocalDefinition val = EmitFieldLoadReceiver(receiverOpt); if (val != null) { FreeTemp(val); } if (fieldSymbol.IsVolatile) { _builder.EmitOpCode(ILOpCode.Volatile); } _builder.EmitOpCode(ILOpCode.Ldfld); EmitSymbolToken(fieldSymbol, fieldAccess.Syntax); } private LocalDefinition EmitFieldLoadReceiver(BoundExpression receiver) { if (FieldLoadMustUseRef(receiver) || FieldLoadPrefersRef(receiver)) { if (!EmitFieldLoadReceiverAddress(receiver)) { return EmitReceiverRef(receiver, Binder.AddressKind.ReadOnly); } return null; } EmitExpression(receiver, used: true); return null; } private bool EmitFieldLoadReceiverAddress(BoundExpression receiver) { if (receiver == null || !receiver.Type.IsValueType) { return false; } if (receiver.Kind == BoundKind.Conversion) { BoundConversion boundConversion = (BoundConversion)receiver; if (boundConversion.ConversionKind == ConversionKind.Unboxing) { EmitExpression(boundConversion.Operand, used: true); _builder.EmitOpCode(ILOpCode.Unbox); EmitSymbolToken(receiver.Type, receiver.Syntax); return true; } } else if (receiver.Kind == BoundKind.FieldAccess) { BoundFieldAccess boundFieldAccess = (BoundFieldAccess)receiver; FieldSymbol fieldSymbol = boundFieldAccess.FieldSymbol; if (!fieldSymbol.IsStatic && EmitFieldLoadReceiverAddress(boundFieldAccess.ReceiverOpt)) { _builder.EmitOpCode(ILOpCode.Ldflda); EmitSymbolToken(fieldSymbol, boundFieldAccess.Syntax); return true; } } return false; } private bool FieldLoadPrefersRef(BoundExpression receiver) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Invalid comparison between Unknown and I4 //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Invalid comparison between Unknown and I4 //IL_00b4: Unknown result type (might be due to invalid IL or missing references) if (!receiver.Type.IsVerifierValue()) { return true; } if (receiver.Kind == BoundKind.Conversion && ((BoundConversion)receiver).ConversionKind == ConversionKind.Unboxing) { return true; } if (!HasHome(receiver, Binder.AddressKind.ReadOnly)) { return false; } switch (receiver.Kind) { case BoundKind.Parameter: return (int)((BoundParameter)receiver).ParameterSymbol.RefKind > 0; case BoundKind.Local: return (int)((BoundLocal)receiver).LocalSymbol.RefKind > 0; case BoundKind.Sequence: return FieldLoadPrefersRef(((BoundSequence)receiver).Value); case BoundKind.FieldAccess: { BoundFieldAccess boundFieldAccess = (BoundFieldAccess)receiver; FieldSymbol fieldSymbol = boundFieldAccess.FieldSymbol; if (fieldSymbol.IsStatic || (int)fieldSymbol.RefKind != 0) { return true; } if (DiagnosticsPass.IsNonAgileFieldAccess(boundFieldAccess, ((PEModuleBuilder)_module).Compilation)) { return false; } return FieldLoadPrefersRef(boundFieldAccess.ReceiverOpt); } default: return true; } } internal static bool FieldLoadMustUseRef(BoundExpression expr) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected I4, but got Unknown TypeSymbol type = expr.Type; if (type.IsTypeParameter()) { return true; } SpecialType specialType = type.SpecialType; switch (specialType - 7) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 11: case 12: case 14: case 15: case 31: case 32: case 33: case 34: return true; default: return type.IsEnumType(); } } private static int ParameterSlot(BoundParameter parameter) { ParameterSymbol parameterSymbol = parameter.ParameterSymbol; int num = parameterSymbol.Ordinal; if (!parameterSymbol.ContainingSymbol.IsStatic) { num++; } return num; } private void EmitLocalLoad(BoundLocal local, bool used) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 bool flag = (int)local.LocalSymbol.RefKind > 0; if (IsStackLocal(local.LocalSymbol)) { EmitPopIfUnused(used || flag); } else { if (!(used || flag)) { return; } LocalDefinition local2 = GetLocal(local); _builder.EmitLocalLoad(local2); } if (flag) { EmitLoadIndirect(local.LocalSymbol.Type, local.Syntax); EmitPopIfUnused(used); } } private void EmitParameterLoad(BoundParameter parameter) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) int num = ParameterSlot(parameter); _builder.EmitLoadArgumentOpcode(num); if ((int)parameter.ParameterSymbol.RefKind != 0) { TypeSymbol type = parameter.ParameterSymbol.Type; EmitLoadIndirect(type, parameter.Syntax); } } private void EmitLoadIndirect(TypeSymbol type, SyntaxNode syntaxNode) { //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) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected I4, but got Unknown if (type.IsEnumType()) { type = ((NamedTypeSymbol)type).EnumUnderlyingType; } PrimitiveTypeCode primitiveTypeCode = type.PrimitiveTypeCode; switch ((int)primitiveTypeCode) { case 2: _builder.EmitOpCode(ILOpCode.Ldind_i1); return; case 0: case 12: _builder.EmitOpCode(ILOpCode.Ldind_u1); return; case 5: _builder.EmitOpCode(ILOpCode.Ldind_i2); return; case 1: case 13: _builder.EmitOpCode(ILOpCode.Ldind_u2); return; case 6: _builder.EmitOpCode(ILOpCode.Ldind_i4); return; case 14: _builder.EmitOpCode(ILOpCode.Ldind_u4); return; case 7: case 15: _builder.EmitOpCode(ILOpCode.Ldind_i8); return; case 8: case 9: case 16: case 19: _builder.EmitOpCode(ILOpCode.Ldind_i); return; case 3: _builder.EmitOpCode(ILOpCode.Ldind_r4); return; case 4: _builder.EmitOpCode(ILOpCode.Ldind_r8); return; } if (type.IsVerifierReference()) { _builder.EmitOpCode(ILOpCode.Ldind_ref); return; } _builder.EmitOpCode(ILOpCode.Ldobj); EmitSymbolToken(type, syntaxNode); } private bool CanUseCallOnRefTypeReceiver(BoundExpression receiver) { //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Invalid comparison between Unknown and I4 if (receiver.Type.IsTypeParameter()) { return false; } ConstantValue constantValueOpt = receiver.ConstantValueOpt; if (constantValueOpt != (ConstantValue)null) { return !constantValueOpt.IsNull; } switch (receiver.Kind) { case BoundKind.ArrayCreation: return true; case BoundKind.ObjectCreationExpression: return true; case BoundKind.Conversion: { BoundConversion boundConversion = (BoundConversion)receiver; switch (boundConversion.ConversionKind) { case ConversionKind.Boxing: return true; case ConversionKind.AnonymousFunction: case ConversionKind.MethodGroup: return true; case ConversionKind.ImplicitReference: case ConversionKind.ExplicitReference: return CanUseCallOnRefTypeReceiver(boundConversion.Operand); } break; } case BoundKind.ThisReference: return true; case BoundKind.FieldAccess: return ((BoundFieldAccess)receiver).FieldSymbol.IsCapturedFrame; case BoundKind.Local: return (int)((BoundLocal)receiver).LocalSymbol.SynthesizedKind == -5; case BoundKind.DelegateCreationExpression: return true; case BoundKind.Sequence: { BoundExpression value = ((BoundSequence)receiver).Value; return CanUseCallOnRefTypeReceiver(value); } case BoundKind.AssignmentOperator: { BoundExpression right = ((BoundAssignmentOperator)receiver).Right; return CanUseCallOnRefTypeReceiver(right); } case BoundKind.TypeOfOperator: return true; case BoundKind.ConditionalReceiver: return true; } return false; } private bool IsThisReceiver(BoundExpression receiver) { switch (receiver.Kind) { case BoundKind.ThisReference: return true; case BoundKind.Sequence: { BoundExpression value = ((BoundSequence)receiver).Value; return IsThisReceiver(value); } default: return false; } } private void EmitCallExpression(BoundCall call, UseKind useKind) { if (call.Method.IsDefaultValueTypeConstructor()) { EmitDefaultValueTypeConstructorCallExpression(call); } else if (!call.Method.RequiresInstanceReceiver) { EmitStaticCallExpression(call, useKind); } else { EmitInstanceCallExpression(call, useKind); } } [MethodImpl(MethodImplOptions.NoInlining)] private void EmitDefaultValueTypeConstructorCallExpression(BoundCall call) { MethodSymbol method = call.Method; BoundExpression receiverOpt = call.ReceiverOpt; LocalDefinition temp = EmitReceiverRef(receiverOpt, Binder.AddressKind.Writeable); _builder.EmitOpCode(ILOpCode.Initobj); EmitSymbolToken(method.ContainingType, call.Syntax); FreeOptTemp(temp); } [MethodImpl(MethodImplOptions.NoInlining)] private void EmitStaticCallExpression(BoundCall call, UseKind useKind) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Invalid comparison between Unknown and I4 MethodSymbol method = call.Method; BoundExpression receiverOpt = call.ReceiverOpt; ImmutableArray arguments = call.Arguments; EmitArguments(arguments, method.Parameters, call.ArgumentRefKindsOpt); int callStackBehavior = GetCallStackBehavior(method, arguments); if (method.IsAbstract || method.IsVirtual) { if (receiverOpt is BoundTypeExpression boundTypeExpression) { TypeSymbol type = boundTypeExpression.Type; if ((object)type != null && (int)type.TypeKind == 11) { _builder.EmitOpCode(ILOpCode.Constrained); EmitSymbolToken(receiverOpt.Type, receiverOpt.Syntax); goto IL_0096; } } throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs", 1644); } goto IL_0096; IL_0096: _builder.EmitOpCode(ILOpCode.Call, callStackBehavior); EmitSymbolToken(method, call.Syntax, method.IsVararg ? ((BoundArgListOperator)arguments[arguments.Length - 1]) : null); EmitCallCleanup(call.Syntax, useKind, method); } [MethodImpl(MethodImplOptions.NoInlining)] private void EmitInstanceCallExpression(BoundCall call, UseKind useKind) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) CallKind callKind; Binder.AddressKind? addressKind; bool box; LocalDefinition tempOpt; if (receiverIsInstanceCall(call, out var nested)) { ArrayBuilder instance = ArrayBuilder.GetInstance(); ArrayBuilderExtensions.Push(instance, call); call = nested; while (receiverIsInstanceCall(call, out nested)) { ArrayBuilderExtensions.Push(instance, call); call = nested; } callKind = determineEmitReceiverStrategy(call, out addressKind, out box); emitReceiver(call, callKind, addressKind, box, out tempOpt); while (instance.Count != 0) { BoundCall boundCall = ArrayBuilderExtensions.Pop(instance); CallKind num = determineEmitReceiverStrategy(boundCall, out addressKind, out box); TypeSymbol type = call.Type; UseKind useKind2; if (!addressKind.HasValue) { useKind2 = UseKind.UsedAsValue; } else if (BoxNonVerifierReferenceReceiver(type, addressKind.GetValueOrDefault())) { useKind2 = UseKind.UsedAsValue; box = true; } else { _ = call.Method.RefKind; useKind2 = ((!UseCallResultAsAddress(call, addressKind.GetValueOrDefault())) ? UseKind.UsedAsValue : UseKind.UsedAsAddress); } emitArgumentsAndCallEpilogue(call, callKind, useKind2); FreeOptTemp(tempOpt); tempOpt = null; nested = call; call = boundCall; callKind = num; if (box) { EmitBox(type, nested.Syntax); } else if (addressKind.HasValue) { if (useKind2 != UseKind.UsedAsAddress) { tempOpt = AllocateTemp(type, nested.Syntax, (LocalSlotConstraints)0); _builder.EmitLocalStore(tempOpt); _builder.EmitLocalAddress(tempOpt); } emitGenericReceiverCloneIfNecessary(call, callKind, ref tempOpt); } } instance.Free(); } else { callKind = determineEmitReceiverStrategy(call, out addressKind, out box); emitReceiver(call, callKind, addressKind, box, out tempOpt); } emitArgumentsAndCallEpilogue(call, callKind, useKind); FreeOptTemp(tempOpt); [MethodImpl(MethodImplOptions.NoInlining)] CallKind determineEmitReceiverStrategy(BoundCall boundCall2, out Binder.AddressKind? reference2, out bool reference) { MethodSymbol method = boundCall2.Method; BoundExpression receiverOpt = boundCall2.ReceiverOpt; TypeSymbol type2 = receiverOpt.Type; reference = false; CallKind callKind2; if (type2.IsVerifierReference()) { reference2 = null; callKind2 = ((!receiverOpt.SuppressVirtualCalls && (method.IsMetadataVirtual() || !CanUseCallOnRefTypeReceiver(receiverOpt))) ? CallKind.CallVirt : CallKind.Call); } else if (type2.IsVerifierValue()) { NamedTypeSymbol containingType = method.ContainingType; if (containingType.IsVerifierValue()) { reference2 = (IsReadOnlyCall(method, containingType) ? Binder.AddressKind.ReadOnly : Binder.AddressKind.Writeable); callKind2 = ((!MayUseCallForStructMethod(method)) ? CallKind.ConstrainedCallVirt : CallKind.Call); } else if (method.IsMetadataVirtual()) { reference2 = Binder.AddressKind.Writeable; callKind2 = CallKind.ConstrainedCallVirt; } else { reference2 = null; reference = true; callKind2 = CallKind.Call; } } else { callKind2 = ((type2.IsReferenceType && !IsRef(receiverOpt)) ? CallKind.CallVirt : CallKind.ConstrainedCallVirt); reference2 = ((callKind2 == CallKind.ConstrainedCallVirt) ? Binder.AddressKind.Constrained : Binder.AddressKind.Writeable); } return callKind2; } [MethodImpl(MethodImplOptions.NoInlining)] void emitArgumentsAndCallEpilogue(BoundCall boundCall2, CallKind callKind2, UseKind useKind3) { MethodSymbol method = boundCall2.Method; BoundExpression receiverOpt = boundCall2.ReceiverOpt; MethodSymbol methodSymbol = method; if (method.IsOverride && callKind2 != CallKind.Call) { methodSymbol = method.GetConstructedLeastOverriddenMethod(_method.ContainingType, requireSameReturnType: true); } if (callKind2 == CallKind.ConstrainedCallVirt && methodSymbol.ContainingType.IsValueType) { callKind2 = CallKind.Call; } if (callKind2 == CallKind.CallVirt) { if (IsThisReceiver(receiverOpt) && methodSymbol.ContainingType.IsSealed && (object)methodSymbol.ContainingModule == _method.ContainingModule) { callKind2 = CallKind.Call; } else if (methodSymbol.IsMetadataFinal && CanUseCallOnRefTypeReceiver(receiverOpt)) { callKind2 = CallKind.Call; } } ImmutableArray arguments = boundCall2.Arguments; EmitArguments(arguments, method.Parameters, boundCall2.ArgumentRefKindsOpt); int callStackBehavior = GetCallStackBehavior(method, arguments); switch (callKind2) { case CallKind.Call: _builder.EmitOpCode(ILOpCode.Call, callStackBehavior); break; case CallKind.CallVirt: _builder.EmitOpCode(ILOpCode.Callvirt, callStackBehavior); break; case CallKind.ConstrainedCallVirt: _builder.EmitOpCode(ILOpCode.Constrained); EmitSymbolToken(receiverOpt.Type, receiverOpt.Syntax); _builder.EmitOpCode(ILOpCode.Callvirt, callStackBehavior); break; } EmitSymbolToken(methodSymbol, boundCall2.Syntax, methodSymbol.IsVararg ? ((BoundArgListOperator)arguments[arguments.Length - 1]) : null); EmitCallCleanup(boundCall2.Syntax, useKind3, method); } [MethodImpl(MethodImplOptions.NoInlining)] void emitGenericReceiverCloneIfNecessary(BoundCall boundCall2, CallKind callKind2, ref LocalDefinition reference) { BoundExpression receiverOpt = boundCall2.ReceiverOpt; TypeSymbol type2 = receiverOpt.Type; if (callKind2 == CallKind.ConstrainedCallVirt && reference == null && !type2.IsValueType && !ReceiverIsKnownToReferToTempIfReferenceType(receiverOpt) && !IsSafeToDereferenceReceiverRefAfterEvaluatingArguments(boundCall2.Arguments)) { object obj = null; if (!type2.IsReferenceType) { EmitDefaultValue(type2, used: true, receiverOpt.Syntax); EmitBox(type2, receiverOpt.Syntax); obj = new object(); _builder.EmitBranch(ILOpCode.Brtrue, obj, ILOpCode.Nop); } EmitLoadIndirect(type2, receiverOpt.Syntax); reference = AllocateTemp(type2, receiverOpt.Syntax, (LocalSlotConstraints)0); _builder.EmitLocalStore(reference); _builder.EmitLocalAddress(reference); if (obj != null) { _builder.MarkLabel(obj); } } } [MethodImpl(MethodImplOptions.NoInlining)] void emitReceiver(BoundCall boundCall2, CallKind callKind2, Binder.AddressKind? addressKind2, bool flag, out LocalDefinition reference) { BoundExpression receiverOpt = boundCall2.ReceiverOpt; TypeSymbol type2 = receiverOpt.Type; reference = null; if (!addressKind2.HasValue) { EmitExpression(receiverOpt, used: true); if (flag) { EmitBox(type2, receiverOpt.Syntax); } } else { reference = EmitReceiverRef(receiverOpt, addressKind2.GetValueOrDefault()); emitGenericReceiverCloneIfNecessary(boundCall2, callKind2, ref reference); } } static bool receiverIsInstanceCall(BoundCall boundCall3, out BoundCall reference) { if (boundCall3.ReceiverOpt is BoundCall boundCall2) { MethodSymbol method = boundCall2.Method; if ((object)method != null && method.RequiresInstanceReceiver && !method.IsDefaultValueTypeConstructor()) { reference = boundCall2; return true; } } reference = null; return false; } } internal static bool IsPossibleReferenceTypeReceiverOfConstrainedCall(BoundExpression receiver) { TypeSymbol type = receiver.Type; if (type.IsVerifierReference() || type.IsVerifierValue()) { return false; } return !type.IsValueType; } internal static bool ReceiverIsKnownToReferToTempIfReferenceType(BoundExpression receiver) { while (receiver is BoundSequence boundSequence) { receiver = boundSequence.Value; } if (receiver is BoundLocal boundLocal) { LocalSymbol localSymbol = boundLocal.LocalSymbol; if ((object)localSymbol != null && localSymbol.IsKnownToReferToTempIfReferenceType) { goto IL_0062; } } else { if (receiver is BoundComplexConditionalReceiver) { goto IL_0062; } if (receiver is BoundConditionalReceiver boundConditionalReceiver) { TypeSymbol type = boundConditionalReceiver.Type; if ((object)type != null && !type.IsReferenceType && !type.IsValueType) { goto IL_0062; } } } bool flag = false; goto IL_006a; IL_006a: if (flag) { return true; } return false; IL_0062: flag = true; goto IL_006a; } internal static bool IsSafeToDereferenceReceiverRefAfterEvaluatingArguments(ImmutableArray arguments) { return arguments.All(isSafeToDereferenceReceiverRefAfterEvaluatingArgument); static bool isSafeToDereferenceReceiverRefAfterEvaluatingArgument(BoundExpression expression) { BoundExpression boundExpression = expression; while (!(boundExpression.ConstantValueOpt != (ConstantValue)null)) { switch (boundExpression.Kind) { default: return false; case BoundKind.TypeExpression: case BoundKind.ThisReference: case BoundKind.Local: case BoundKind.Parameter: return true; case BoundKind.FieldAccess: boundExpression = ((BoundFieldAccess)boundExpression).ReceiverOpt; if (boundExpression == null) { return true; } break; case BoundKind.PassByCopy: boundExpression = ((BoundPassByCopy)boundExpression).Expression; break; case BoundKind.BinaryOperator: { BoundBinaryOperator boundBinaryOperator = (BoundBinaryOperator)boundExpression; if (boundBinaryOperator.OperatorKind.IsUserDefined() || !isSafeToDereferenceReceiverRefAfterEvaluatingArgument(boundBinaryOperator.Right)) { return false; } boundExpression = boundBinaryOperator.Left; break; } case BoundKind.Conversion: { BoundConversion boundConversion = (BoundConversion)boundExpression; if (boundConversion.ConversionKind.IsUserDefinedConversion()) { return false; } boundExpression = boundConversion.Operand; break; } } } return true; } } private bool IsReadOnlyCall(MethodSymbol method, NamedTypeSymbol methodContainingType) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 if (method.IsEffectivelyReadOnly && (int)method.MethodKind != 1) { return true; } if (methodContainingType.IsNullableType()) { MethodSymbol originalDefinition = method.OriginalDefinition; if ((object)originalDefinition == ((PEModuleBuilder)_module).Compilation.GetSpecialTypeMember((SpecialMember)114) || (object)originalDefinition == ((PEModuleBuilder)_module).Compilation.GetSpecialTypeMember((SpecialMember)115) || (object)originalDefinition == ((PEModuleBuilder)_module).Compilation.GetSpecialTypeMember((SpecialMember)116)) { return true; } } return false; } internal static bool IsRef(BoundExpression receiver) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Invalid comparison between Unknown and I4 //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Invalid comparison between Unknown and I4 //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Invalid comparison between Unknown and I4 //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Invalid comparison between Unknown and I4 //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 return receiver.Kind switch { BoundKind.Local => (int)((BoundLocal)receiver).LocalSymbol.RefKind > 0, BoundKind.Parameter => (int)((BoundParameter)receiver).ParameterSymbol.RefKind > 0, BoundKind.Call => (int)((BoundCall)receiver).Method.RefKind > 0, BoundKind.FunctionPointerInvocation => (int)((BoundFunctionPointerInvocation)receiver).FunctionPointer.Signature.RefKind > 0, BoundKind.Dup => (int)((BoundDup)receiver).RefKind > 0, BoundKind.Sequence => IsRef(((BoundSequence)receiver).Value), _ => false, }; } private static int GetCallStackBehavior(MethodSymbol method, ImmutableArray arguments) { int num = 0; if (!method.ReturnsVoid) { num++; } if (method.RequiresInstanceReceiver) { num--; } if (method.IsVararg) { int num2 = arguments.Length - 1; int length = ((BoundArgListOperator)arguments[num2]).Arguments.Length; num -= num2; return num - length; } return num - arguments.Length; } private static int GetObjCreationStackBehavior(BoundObjectCreationExpression objCreation) { int num = 0; num++; if (objCreation.Constructor.IsVararg) { int num2 = objCreation.Arguments.Length - 1; int length = ((BoundArgListOperator)objCreation.Arguments[num2]).Arguments.Length; num -= num2; return num - length; } return num - objCreation.Arguments.Length; } internal static bool MayUseCallForStructMethod(MethodSymbol method) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 if (!method.IsMetadataVirtual() || method.IsStatic) { return true; } MethodSymbol overriddenMethod = method.OverriddenMethod; if ((object)overriddenMethod == null || overriddenMethod.IsAbstract) { return true; } return (int)method.ContainingType.SpecialType > 0; } private void TreatLongsAsNative(PrimitiveTypeCode tc) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 if ((int)tc == 7) { _builder.EmitOpCode(ILOpCode.Conv_ovf_i); } else if ((int)tc == 15) { _builder.EmitOpCode(ILOpCode.Conv_ovf_i_un); } } private void EmitArrayLength(BoundArrayLength expression, bool used) { //IL_0023: 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_0029: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) EmitExpression(expression.Expression, used: true); _builder.EmitOpCode(ILOpCode.Ldlen); PrimitiveTypeCode primitiveTypeCode = expression.Type.PrimitiveTypeCode; PrimitiveTypeCode val = (PrimitiveTypeCode)(PrimitiveTypeCodeExtensions.IsUnsigned(primitiveTypeCode) ? 16 : 8); _builder.EmitNumericConversion(val, primitiveTypeCode, false); EmitPopIfUnused(used); } private void EmitArrayCreationExpression(BoundArrayCreation expression, bool used) { ArrayTypeSymbol arrayTypeSymbol = (ArrayTypeSymbol)expression.Type; EmitArrayIndices(expression.Bounds); if (arrayTypeSymbol.IsSZArray) { _builder.EmitOpCode(ILOpCode.Newarr); EmitSymbolToken(arrayTypeSymbol.ElementType, expression.Syntax); } else { _builder.EmitArrayCreation(_module.Translate(arrayTypeSymbol), expression.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); } if (expression.InitializerOpt != null) { EmitArrayInitializers(arrayTypeSymbol, expression.InitializerOpt); } EmitPopIfUnused(used); } private void EmitConvertedStackAllocExpression(BoundConvertedStackAllocExpression expression, bool used) { EmitExpression(expression.Count, used); if (used) { _sawStackalloc = true; _builder.EmitOpCode(ILOpCode.Localloc); } BoundArrayInitialization initializerOpt = expression.InitializerOpt; if (initializerOpt == null) { return; } if (used) { EmitStackAllocInitializers(expression.Type, initializerOpt); return; } ImmutableArray.Enumerator enumerator = initializerOpt.Initializers.GetEnumerator(); while (enumerator.MoveNext()) { BoundExpression current = enumerator.Current; EmitExpression(current, used: false); } } private void EmitObjectCreationExpression(BoundObjectCreationExpression expression, bool used) { MethodSymbol constructor = expression.Constructor; bool avoidInPlace; if (constructor.IsDefaultValueTypeConstructor()) { EmitInitObj(expression.Type, used, expression.Syntax); } else if (!used && ConstructorNotSideEffecting(constructor)) { ImmutableArray.Enumerator enumerator = expression.Arguments.GetEnumerator(); while (enumerator.MoveNext()) { BoundExpression current = enumerator.Current; EmitExpression(current, used: false); } } else if (!TryEmitReadonlySpanAsBlobWrapper(expression, used, null, out avoidInPlace)) { EmitArguments(expression.Arguments, constructor.Parameters, expression.ArgumentRefKindsOpt); int objCreationStackBehavior = GetObjCreationStackBehavior(expression); _builder.EmitOpCode(ILOpCode.Newobj, objCreationStackBehavior); EmitSymbolToken(constructor, expression.Syntax, constructor.IsVararg ? ((BoundArgListOperator)expression.Arguments[expression.Arguments.Length - 1]) : null); EmitPopIfUnused(used); } } private bool TryEmitReadonlySpanAsBlobWrapper(BoundObjectCreationExpression expression, bool used, BoundExpression inPlaceTarget, out bool avoidInPlace) { int length = expression.Arguments.Length; avoidInPlace = false; if ((length == 1 && (object)expression.Constructor.OriginalDefinition == ((PEModuleBuilder)_module).Compilation.GetWellKnownTypeMember((WellKnownMember)404)) || (length == 3 && (object)expression.Constructor.OriginalDefinition == ((PEModuleBuilder)_module).Compilation.GetWellKnownTypeMember((WellKnownMember)405))) { return TryEmitReadonlySpanAsBlobWrapper((NamedTypeSymbol)expression.Type, expression.Arguments[0], used, inPlaceTarget, out avoidInPlace, (length == 3) ? expression.Arguments[1] : null, (length == 3) ? expression.Arguments[2] : null); } return false; } private bool ConstructorNotSideEffecting(MethodSymbol constructor) { MethodSymbol originalDefinition = constructor.OriginalDefinition; CSharpCompilation compilation = ((PEModuleBuilder)_module).Compilation; if (originalDefinition == compilation.GetSpecialTypeMember((SpecialMember)117)) { return true; } if (originalDefinition.ContainingType.Name == "ValueTuple" && (originalDefinition == compilation.GetWellKnownTypeMember((WellKnownMember)345) || originalDefinition == compilation.GetWellKnownTypeMember((WellKnownMember)346) || originalDefinition == compilation.GetWellKnownTypeMember((WellKnownMember)347) || originalDefinition == compilation.GetWellKnownTypeMember((WellKnownMember)348) || originalDefinition == compilation.GetWellKnownTypeMember((WellKnownMember)349) || originalDefinition == compilation.GetWellKnownTypeMember((WellKnownMember)350) || originalDefinition == compilation.GetWellKnownTypeMember((WellKnownMember)351) || originalDefinition == compilation.GetWellKnownTypeMember((WellKnownMember)344))) { return true; } return false; } private void EmitAssignmentExpression(BoundAssignmentOperator assignmentOperator, UseKind useKind) { if (!TryEmitAssignmentInPlace(assignmentOperator, useKind != UseKind.Unused)) { bool lhsUsesStack = EmitAssignmentPreamble(assignmentOperator); EmitAssignmentValue(assignmentOperator); LocalDefinition temp = EmitAssignmentDuplication(assignmentOperator, useKind, lhsUsesStack); EmitStore(assignmentOperator); EmitAssignmentPostfix(assignmentOperator, temp, useKind); } } private bool TryEmitAssignmentInPlace(BoundAssignmentOperator assignmentOperator, bool used) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Invalid comparison between Unknown and I4 if (assignmentOperator.IsRef) { return false; } BoundExpression left = assignmentOperator.Left; if (used && !TargetIsNotOnHeap(left)) { return false; } if (!SafeToGetWriteableReference(left)) { return false; } BoundExpression right = assignmentOperator.Right; TypeSymbol type = right.Type; if (!type.IsTypeParameter() && (type.IsReferenceType || (right.ConstantValueOpt != (ConstantValue)null && (int)type.SpecialType != 17))) { return false; } if (right.IsDefaultValue()) { InPlaceInit(left, used); return true; } if (right is BoundObjectCreationExpression boundObjectCreationExpression) { if (boundObjectCreationExpression.Arguments.Length > 0 && boundObjectCreationExpression.Arguments[0].Kind == BoundKind.ConvertedStackAllocExpression) { return false; } if (PartialCtorResultCannotEscape(left)) { MethodSymbol constructor = boundObjectCreationExpression.Constructor; if (constructor.Parameters.All((ParameterSymbol p) => (int)p.RefKind == 0) && !constructor.IsVararg && TryInPlaceCtorCall(left, boundObjectCreationExpression, used)) { return true; } } } return false; } private bool SafeToGetWriteableReference(BoundExpression left) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 if (!HasHome(left, Binder.AddressKind.Writeable)) { return false; } if (left.Kind == BoundKind.ArrayAccess && (int)left.Type.TypeKind == 11 && !left.Type.IsValueType) { return false; } if (left.Kind == BoundKind.FieldAccess) { BoundFieldAccess boundFieldAccess = (BoundFieldAccess)left; if (boundFieldAccess.FieldSymbol.IsVolatile || DiagnosticsPass.IsNonAgileFieldAccess(boundFieldAccess, ((PEModuleBuilder)_module).Compilation)) { return false; } } return true; } private void InPlaceInit(BoundExpression target, bool used) { EmitAddress(target, Binder.AddressKind.Writeable); _builder.EmitOpCode(ILOpCode.Initobj); EmitSymbolToken(target.Type, target.Syntax); if (used) { EmitExpression(target, used); } } private bool TryInPlaceCtorCall(BoundExpression target, BoundObjectCreationExpression objCreation, bool used) { if (TryEmitReadonlySpanAsBlobWrapper(objCreation, used, target, out var avoidInPlace)) { return true; } if (avoidInPlace) { return false; } EmitAddress(target, Binder.AddressKind.Writeable); MethodSymbol constructor = objCreation.Constructor; EmitArguments(objCreation.Arguments, constructor.Parameters, objCreation.ArgumentRefKindsOpt); int num = GetObjCreationStackBehavior(objCreation) - 2; _builder.EmitOpCode(ILOpCode.Call, num); EmitSymbolToken(constructor, objCreation.Syntax, constructor.IsVararg ? ((BoundArgListOperator)objCreation.Arguments[objCreation.Arguments.Length - 1]) : null); if (used) { EmitExpression(target, used: true); } return true; } private bool PartialCtorResultCannotEscape(BoundExpression left) { if (TargetIsNotOnHeap(left)) { if (_tryNestingLevel != 0) { if (left is BoundLocal localExpression && !_builder.PossiblyDefinedOutsideOfTry(GetLocal(localExpression))) { return true; } return false; } return true; } return false; } private static bool TargetIsNotOnHeap(BoundExpression left) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Invalid comparison between Unknown and I4 //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 return left.Kind switch { BoundKind.Parameter => (int)((BoundParameter)left).ParameterSymbol.RefKind == 0, BoundKind.Local => (int)((BoundLocal)left).LocalSymbol.RefKind == 0, _ => false, }; } private bool EmitAssignmentPreamble(BoundAssignmentOperator assignmentOperator) { //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) BoundExpression left = assignmentOperator.Left; bool result = false; switch (left.Kind) { case BoundKind.RefValueOperator: EmitRefValueAddress((BoundRefValueOperator)left); break; case BoundKind.FieldAccess: { BoundFieldAccess boundFieldAccess = (BoundFieldAccess)left; if ((int)boundFieldAccess.FieldSymbol.RefKind != 0 && !assignmentOperator.IsRef) { EmitFieldLoadNoIndirection(boundFieldAccess, used: true); } else if (!boundFieldAccess.FieldSymbol.IsStatic) { EmitReceiverRef(boundFieldAccess.ReceiverOpt, Binder.AddressKind.Writeable); result = true; } break; } case BoundKind.Parameter: { BoundParameter boundParameter = (BoundParameter)left; if ((int)boundParameter.ParameterSymbol.RefKind != 0 && !assignmentOperator.IsRef) { _builder.EmitLoadArgumentOpcode(ParameterSlot(boundParameter)); result = true; } break; } case BoundKind.Local: { BoundLocal boundLocal = (BoundLocal)left; if ((int)boundLocal.LocalSymbol.RefKind != 0 && !assignmentOperator.IsRef) { if (!IsStackLocal(boundLocal.LocalSymbol)) { LocalDefinition local = GetLocal(boundLocal); _builder.EmitLocalLoad(local); } result = true; } break; } case BoundKind.ArrayAccess: { BoundArrayAccess boundArrayAccess = (BoundArrayAccess)left; EmitExpression(boundArrayAccess.Expression, used: true); EmitArrayIndices(boundArrayAccess.Indices); result = true; break; } case BoundKind.ThisReference: { BoundThisReference expression3 = (BoundThisReference)left; EmitAddress(expression3, Binder.AddressKind.Writeable); result = true; break; } case BoundKind.Dup: { BoundDup expression2 = (BoundDup)left; EmitAddress(expression2, Binder.AddressKind.Writeable); result = true; break; } case BoundKind.ConditionalOperator: { BoundConditionalOperator expression = (BoundConditionalOperator)left; EmitAddress(expression, Binder.AddressKind.Writeable); result = true; break; } case BoundKind.PointerIndirectionOperator: { BoundPointerIndirectionOperator boundPointerIndirectionOperator = (BoundPointerIndirectionOperator)left; EmitExpression(boundPointerIndirectionOperator.Operand, used: true); result = true; break; } case BoundKind.Sequence: { BoundSequence boundSequence = (BoundSequence)left; DefineAndRecordLocals(boundSequence); EmitSideEffects(boundSequence); result = EmitAssignmentPreamble(assignmentOperator.Update(boundSequence.Value, assignmentOperator.Right, assignmentOperator.IsRef, assignmentOperator.Type)); CloseScopeAndKeepLocals(boundSequence); break; } case BoundKind.Call: { BoundCall call = (BoundCall)left; EmitCallExpression(call, UseKind.UsedAsAddress); result = true; break; } case BoundKind.FunctionPointerInvocation: { BoundFunctionPointerInvocation ptrInvocation = (BoundFunctionPointerInvocation)left; EmitCalli(ptrInvocation, UseKind.UsedAsAddress); result = true; break; } case BoundKind.PreviousSubmissionReference: case BoundKind.PropertyAccess: case BoundKind.IndexerAccess: throw ExceptionUtilities.UnexpectedValue((object)left.Kind); case BoundKind.PseudoVariable: EmitPseudoVariableAddress((BoundPseudoVariable)left); result = true; break; case BoundKind.AssignmentOperator: { BoundAssignmentOperator boundAssignmentOperator = (BoundAssignmentOperator)left; if (boundAssignmentOperator.IsRef) { EmitAssignmentExpression(boundAssignmentOperator, UseKind.UsedAsAddress); break; } goto default; } default: throw ExceptionUtilities.UnexpectedValue((object)left.Kind); case BoundKind.InstrumentationPayloadRoot: case BoundKind.ModuleVersionId: break; } return result; } private void EmitAssignmentValue(BoundAssignmentOperator assignmentOperator) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Invalid comparison between Unknown and I4 //IL_008f: Unknown result type (might be due to invalid IL or missing references) if (!assignmentOperator.IsRef) { EmitExpression(assignmentOperator.Right, used: true); return; } int num = _expressionTemps?.Count ?? 0; BoundExpression left = assignmentOperator.Left; BoundExpression right = assignmentOperator.Right; RefKind refKind = left.GetRefKind(); bool flag = refKind - 3 <= 2; LocalDefinition temp = EmitAddress(right, flag ? Binder.AddressKind.ReadOnlyStrict : Binder.AddressKind.Writeable); AddExpressionTemp(temp); int num2 = _expressionTemps?.Count ?? 0; if (left.Kind == BoundKind.Local && SynthesizedLocalKindExtensions.IsLongLived(((BoundLocal)left).LocalSymbol.SynthesizedKind) && num2 > num) { _expressionTemps.Count = num; } } private LocalDefinition EmitAssignmentDuplication(BoundAssignmentOperator assignmentOperator, UseKind useKind, bool lhsUsesStack) { LocalDefinition val = null; if (useKind != UseKind.Unused) { _builder.EmitOpCode(ILOpCode.Dup); if (lhsUsesStack) { val = AllocateTemp(assignmentOperator.Left.Type, assignmentOperator.Left.Syntax, (LocalSlotConstraints)(assignmentOperator.IsRef ? 1 : 0)); _builder.EmitLocalStore(val); } } return val; } private void EmitStore(BoundAssignmentOperator assignment) { //IL_00fd: Unknown result type (might be due to invalid IL or missing references) BoundExpression left = assignment.Left; switch (left.Kind) { case BoundKind.FieldAccess: EmitFieldStore((BoundFieldAccess)left, assignment.IsRef); return; case BoundKind.Local: { BoundLocal boundLocal = (BoundLocal)left; if ((int)boundLocal.LocalSymbol.RefKind != 0 && !assignment.IsRef) { EmitIndirectStore(boundLocal.LocalSymbol.Type, boundLocal.Syntax); } else if (!IsStackLocal(boundLocal.LocalSymbol)) { _builder.EmitLocalStore(GetLocal(boundLocal)); } return; } case BoundKind.ArrayAccess: { ArrayTypeSymbol arrayType = (ArrayTypeSymbol)((BoundArrayAccess)left).Expression.Type; EmitArrayElementStore(arrayType, left.Syntax); return; } case BoundKind.ThisReference: EmitThisStore((BoundThisReference)left); return; case BoundKind.Parameter: EmitParameterStore((BoundParameter)left, assignment.IsRef); return; case BoundKind.Dup: EmitIndirectStore(left.Type, left.Syntax); return; case BoundKind.ConditionalOperator: EmitIndirectStore(left.Type, left.Syntax); return; case BoundKind.PointerIndirectionOperator: case BoundKind.RefValueOperator: case BoundKind.PseudoVariable: EmitIndirectStore(left.Type, left.Syntax); return; case BoundKind.Sequence: { BoundSequence boundSequence = (BoundSequence)left; EmitStore(assignment.Update(boundSequence.Value, assignment.Right, assignment.IsRef, assignment.Type)); return; } case BoundKind.Call: EmitIndirectStore(left.Type, left.Syntax); return; case BoundKind.FunctionPointerInvocation: EmitIndirectStore(left.Type, left.Syntax); return; case BoundKind.ModuleVersionId: EmitModuleVersionIdStore((BoundModuleVersionId)left); return; case BoundKind.InstrumentationPayloadRoot: EmitInstrumentationPayloadRootStore((BoundInstrumentationPayloadRoot)left); return; case BoundKind.AssignmentOperator: { BoundAssignmentOperator boundAssignmentOperator = (BoundAssignmentOperator)left; if (boundAssignmentOperator.IsRef) { EmitIndirectStore(boundAssignmentOperator.Type, left.Syntax); return; } break; } } throw ExceptionUtilities.UnexpectedValue((object)left.Kind); } private void EmitAssignmentPostfix(BoundAssignmentOperator assignment, LocalDefinition temp, UseKind useKind) { if (temp != null) { if (useKind == UseKind.UsedAsAddress) { _builder.EmitLocalAddress(temp); } else { _builder.EmitLocalLoad(temp); } FreeTemp(temp); } if (useKind == UseKind.UsedAsValue && assignment.IsRef) { EmitLoadIndirect(assignment.Type, assignment.Syntax); } } private void EmitThisStore(BoundThisReference thisRef) { _builder.EmitOpCode(ILOpCode.Stobj); EmitSymbolToken(thisRef.Type, thisRef.Syntax); } private void EmitArrayElementStore(ArrayTypeSymbol arrayType, SyntaxNode syntaxNode) { if (arrayType.IsSZArray) { EmitVectorElementStore(arrayType, syntaxNode); } else { _builder.EmitArrayElementStore(_module.Translate(arrayType), syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); } } private void EmitVectorElementStore(ArrayTypeSymbol arrayType, SyntaxNode syntaxNode) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected I4, but got Unknown TypeSymbol typeSymbol = arrayType.ElementType; if (typeSymbol.IsEnumType()) { typeSymbol = ((NamedTypeSymbol)typeSymbol).EnumUnderlyingType; } PrimitiveTypeCode primitiveTypeCode = typeSymbol.PrimitiveTypeCode; switch ((int)primitiveTypeCode) { case 0: case 2: case 12: _builder.EmitOpCode(ILOpCode.Stelem_i1); return; case 1: case 5: case 13: _builder.EmitOpCode(ILOpCode.Stelem_i2); return; case 6: case 14: _builder.EmitOpCode(ILOpCode.Stelem_i4); return; case 7: case 15: _builder.EmitOpCode(ILOpCode.Stelem_i8); return; case 8: case 9: case 16: case 19: _builder.EmitOpCode(ILOpCode.Stelem_i); return; case 3: _builder.EmitOpCode(ILOpCode.Stelem_r4); return; case 4: _builder.EmitOpCode(ILOpCode.Stelem_r8); return; } if (typeSymbol.IsVerifierReference()) { _builder.EmitOpCode(ILOpCode.Stelem_ref); return; } _builder.EmitOpCode(ILOpCode.Stelem); EmitSymbolToken(typeSymbol, syntaxNode); } private void EmitFieldStore(BoundFieldAccess fieldAccess, bool refAssign) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) FieldSymbol fieldSymbol = fieldAccess.FieldSymbol; if (fieldSymbol.IsVolatile) { _builder.EmitOpCode(ILOpCode.Volatile); } if ((int)fieldSymbol.RefKind != 0 && !refAssign) { EmitIndirectStore(fieldSymbol.Type, fieldAccess.Syntax); return; } _builder.EmitOpCode(fieldSymbol.IsStatic ? ILOpCode.Stsfld : ILOpCode.Stfld); EmitSymbolToken(fieldSymbol, fieldAccess.Syntax); } private void EmitParameterStore(BoundParameter parameter, bool refAssign) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if ((int)parameter.ParameterSymbol.RefKind != 0 && !refAssign) { EmitIndirectStore(parameter.ParameterSymbol.Type, parameter.Syntax); return; } int num = ParameterSlot(parameter); _builder.EmitStoreArgumentOpcode(num); } private void EmitIndirectStore(TypeSymbol type, SyntaxNode syntaxNode) { //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) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected I4, but got Unknown if (type.IsEnumType()) { type = ((NamedTypeSymbol)type).EnumUnderlyingType; } PrimitiveTypeCode primitiveTypeCode = type.PrimitiveTypeCode; switch ((int)primitiveTypeCode) { case 0: case 2: case 12: _builder.EmitOpCode(ILOpCode.Stind_i1); return; case 1: case 5: case 13: _builder.EmitOpCode(ILOpCode.Stind_i2); return; case 6: case 14: _builder.EmitOpCode(ILOpCode.Stind_i4); return; case 7: case 15: _builder.EmitOpCode(ILOpCode.Stind_i8); return; case 8: case 9: case 16: case 19: _builder.EmitOpCode(ILOpCode.Stind_i); return; case 3: _builder.EmitOpCode(ILOpCode.Stind_r4); return; case 4: _builder.EmitOpCode(ILOpCode.Stind_r8); return; } if (type.IsVerifierReference()) { _builder.EmitOpCode(ILOpCode.Stind_ref); return; } _builder.EmitOpCode(ILOpCode.Stobj); EmitSymbolToken(type, syntaxNode); } private void EmitPopIfUnused(bool used) { if (!used) { _builder.EmitOpCode(ILOpCode.Pop); } } private void EmitIsExpression(BoundIsOperator isOp, bool used, bool omitBooleanConversion) { BoundExpression operand = isOp.Operand; EmitExpression(operand, used); if (used) { if (!operand.Type.IsVerifierReference()) { EmitBox(operand.Type, operand.Syntax); } _builder.EmitOpCode(ILOpCode.Isinst); EmitSymbolToken(isOp.TargetType.Type, isOp.Syntax); if (!omitBooleanConversion) { _builder.EmitOpCode(ILOpCode.Ldnull); _builder.EmitOpCode(ILOpCode.Cgt_un); } } } private void EmitAsExpression(BoundAsOperator asOp, bool used) { BoundExpression operand = asOp.Operand; EmitExpression(operand, used); if (used) { TypeSymbol type = operand.Type; TypeSymbol type2 = asOp.Type; if ((object)type != null && !type.IsVerifierReference()) { EmitBox(type, operand.Syntax); } _builder.EmitOpCode(ILOpCode.Isinst); EmitSymbolToken(type2, asOp.Syntax); if (!type2.IsVerifierReference()) { _builder.EmitOpCode(ILOpCode.Unbox_any); EmitSymbolToken(type2, asOp.Syntax); } } } private void EmitDefaultValue(TypeSymbol type, bool used, SyntaxNode syntaxNode) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Invalid comparison between Unknown and I4 //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Invalid comparison between Unknown and I4 if (!used) { return; } if (!type.IsTypeParameter() && (int)type.SpecialType != 17) { ConstantValue defaultValue = type.GetDefaultValue(); if (defaultValue != (ConstantValue)null) { _builder.EmitConstantValue(defaultValue); return; } } if (type.IsPointerOrFunctionPointer() || (int)type.SpecialType == 22) { _builder.EmitOpCode(ILOpCode.Ldc_i4_0); _builder.EmitOpCode(ILOpCode.Conv_u); } else if ((int)type.SpecialType == 21) { _builder.EmitOpCode(ILOpCode.Ldc_i4_0); _builder.EmitOpCode(ILOpCode.Conv_i); } else { EmitInitObj(type, used: true, syntaxNode); } } private void EmitDefaultExpression(BoundDefaultExpression expression, bool used) { EmitDefaultValue(expression.Type, used, expression.Syntax); } private void EmitConstantExpression(TypeSymbol type, ConstantValue constantValue, bool used, SyntaxNode syntaxNode) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 if (used) { if ((object)type != null && (int)type.TypeKind == 11 && constantValue.IsNull) { EmitInitObj(type, used, syntaxNode); } else { _builder.EmitConstantValue(constantValue); } } } private void EmitInitObj(TypeSymbol type, bool used, SyntaxNode syntaxNode) { if (used) { LocalDefinition val = AllocateTemp(type, syntaxNode, (LocalSlotConstraints)0); _builder.EmitLocalAddress(val); _builder.EmitOpCode(ILOpCode.Initobj); EmitSymbolToken(type, syntaxNode); _builder.EmitLocalLoad(val); FreeTemp(val); } } private void EmitGetTypeFromHandle(BoundTypeOf boundTypeOf) { _builder.EmitOpCode(ILOpCode.Call, 0); MethodSymbol getTypeFromHandle = boundTypeOf.GetTypeFromHandle; EmitSymbolToken(getTypeFromHandle, boundTypeOf.Syntax, null); } private void EmitTypeOfExpression(BoundTypeOfOperator boundTypeOfOperator) { TypeSymbol type = boundTypeOfOperator.SourceType.Type; _builder.EmitOpCode(ILOpCode.Ldtoken); EmitSymbolToken(type, boundTypeOfOperator.SourceType.Syntax); EmitGetTypeFromHandle(boundTypeOfOperator); } private void EmitSizeOfExpression(BoundSizeOfOperator boundSizeOfOperator) { TypeSymbol type = boundSizeOfOperator.SourceType.Type; _builder.EmitOpCode(ILOpCode.Sizeof); EmitSymbolToken(type, boundSizeOfOperator.SourceType.Syntax); } private void EmitMethodDefIndexExpression(BoundMethodDefIndex node) { _builder.EmitOpCode(ILOpCode.Ldtoken); MethodSymbol method = node.Method.PartialDefinitionPart ?? node.Method; EmitSymbolToken(method, node.Syntax, null, encodeAsRawDefinitionToken: true); } private void EmitLocalIdExpression(BoundLocalId node) { if ((object)node.HoistedField == null) { _builder.EmitIntConstant(GetLocal(node.Local).SlotIndex); } else { EmitHoistedVariableId(node.HoistedField, node.Syntax); } } private void EmitParameterIdExpression(BoundParameterId node) { if ((object)node.HoistedField == null) { _builder.EmitIntConstant(node.Parameter.Ordinal); } else { EmitHoistedVariableId(node.HoistedField, node.Syntax); } } private void EmitHoistedVariableId(FieldSymbol field, SyntaxNode syntax) { IFieldReference val = _module.Translate(field, syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag, needDeclaration: true); _builder.EmitOpCode(ILOpCode.Ldtoken); _builder.EmitToken((IReference)(object)val, syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag, (RawTokenEncoding)4); } private void EmitMaximumMethodDefIndexExpression(BoundMaximumMethodDefIndex node) { _builder.EmitOpCode(ILOpCode.Ldtoken); _builder.EmitGreatestMethodToken(); } private void EmitModuleVersionIdLoad(BoundModuleVersionId node) { _builder.EmitOpCode(ILOpCode.Ldsfld); EmitModuleVersionIdToken(node); } private void EmitModuleVersionIdStore(BoundModuleVersionId node) { _builder.EmitOpCode(ILOpCode.Stsfld); EmitModuleVersionIdToken(node); } private void EmitModuleVersionIdToken(BoundModuleVersionId node) { _builder.EmitToken((IReference)(object)((PEModuleBuilder)_module).GetModuleVersionId(((PEModuleBuilder)_module).Translate(node.Type, node.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag), node.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag), node.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag, (RawTokenEncoding)0); } private void EmitModuleVersionIdStringLoad() { _builder.EmitOpCode(ILOpCode.Ldstr); _builder.EmitModuleVersionIdStringToken(); } private void EmitInstrumentationPayloadRootLoad(BoundInstrumentationPayloadRoot node) { _builder.EmitOpCode(ILOpCode.Ldsfld); EmitInstrumentationPayloadRootToken(node); } private void EmitInstrumentationPayloadRootStore(BoundInstrumentationPayloadRoot node) { _builder.EmitOpCode(ILOpCode.Stsfld); EmitInstrumentationPayloadRootToken(node); } private void EmitInstrumentationPayloadRootToken(BoundInstrumentationPayloadRoot node) { _builder.EmitToken((IReference)(object)((PEModuleBuilder)_module).GetInstrumentationPayloadRoot(node.AnalysisKind, ((PEModuleBuilder)_module).Translate(node.Type, node.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag), node.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag), node.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag, (RawTokenEncoding)0); } private void EmitSourceDocumentIndex(BoundSourceDocumentIndex node) { _builder.EmitOpCode(ILOpCode.Ldtoken); _builder.EmitSourceDocumentIndexToken(node.Document); } private void EmitMethodInfoExpression(BoundMethodInfo node) { _builder.EmitOpCode(ILOpCode.Ldtoken); EmitSymbolToken(node.Method, node.Syntax, null); MethodSymbol getMethodFromHandle = node.GetMethodFromHandle; if (getMethodFromHandle.ParameterCount == 1) { _builder.EmitOpCode(ILOpCode.Call, 0); } else { _builder.EmitOpCode(ILOpCode.Ldtoken); EmitSymbolToken(node.Method.ContainingType, node.Syntax); _builder.EmitOpCode(ILOpCode.Call, -1); } EmitSymbolToken(getMethodFromHandle, node.Syntax, null); if (!TypeSymbol.Equals(node.Type, getMethodFromHandle.ReturnType, (TypeCompareKind)0)) { _builder.EmitOpCode(ILOpCode.Castclass); EmitSymbolToken(node.Type, node.Syntax); } } private void EmitFieldInfoExpression(BoundFieldInfo node) { _builder.EmitOpCode(ILOpCode.Ldtoken); EmitSymbolToken(node.Field, node.Syntax); MethodSymbol getFieldFromHandle = node.GetFieldFromHandle; if (getFieldFromHandle.ParameterCount == 1) { _builder.EmitOpCode(ILOpCode.Call, 0); } else { _builder.EmitOpCode(ILOpCode.Ldtoken); EmitSymbolToken(node.Field.ContainingType, node.Syntax); _builder.EmitOpCode(ILOpCode.Call, -1); } EmitSymbolToken(getFieldFromHandle, node.Syntax, null); if (!TypeSymbol.Equals(node.Type, getFieldFromHandle.ReturnType, (TypeCompareKind)0)) { _builder.EmitOpCode(ILOpCode.Castclass); EmitSymbolToken(node.Type, node.Syntax); } } private void EmitConditionalOperator(BoundConditionalOperator expr, bool used) { //IL_0004: 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_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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (used && (int)_ilEmitStyle != 0 && (IsNumeric(expr.Type) || (int)expr.Type.PrimitiveTypeCode == 0) && hasIntegralValueZeroOrOne(expr.Consequence, out var isOne) && hasIntegralValueZeroOrOne(expr.Alternative, out var isOne2) && isOne != isOne2 && TryEmitComparison(expr.Condition, isOne)) { PrimitiveTypeCode primitiveTypeCode = expr.Type.PrimitiveTypeCode; if ((int)primitiveTypeCode != 0) { _builder.EmitNumericConversion((PrimitiveTypeCode)6, primitiveTypeCode, false); } return; } object dest = new object(); object obj = new object(); EmitCondBranch(expr.Condition, ref dest, sense: true); EmitExpression(expr.Alternative, used); TypeSymbol typeSymbol = StackMergeType(expr.Alternative); if (used) { if (IsVarianceCast(expr.Type, typeSymbol)) { EmitStaticCast(expr.Type, expr.Syntax); typeSymbol = expr.Type; } else if (expr.Type.IsInterfaceType() && !TypeSymbol.Equals(expr.Type, typeSymbol, (TypeCompareKind)0)) { EmitStaticCast(expr.Type, expr.Syntax); } } _builder.EmitBranch(ILOpCode.Br, obj, ILOpCode.Nop); if (used) { _builder.AdjustStack(-1); } _builder.MarkLabel(dest); EmitExpression(expr.Consequence, used); if (used) { TypeSymbol typeSymbol2 = StackMergeType(expr.Consequence); if (IsVarianceCast(expr.Type, typeSymbol2)) { EmitStaticCast(expr.Type, expr.Syntax); typeSymbol2 = expr.Type; } else if (expr.Type.IsInterfaceType() && !TypeSymbol.Equals(expr.Type, typeSymbol2, (TypeCompareKind)0)) { EmitStaticCast(expr.Type, expr.Syntax); } } _builder.MarkLabel(obj); static bool hasIntegralValueZeroOrOne(BoundExpression boundExpression, out bool reference) { ConstantValue constantValueOpt = boundExpression.ConstantValueOpt; ulong uInt64Value = default(ulong); bool flag; if (constantValueOpt != null) { if (constantValueOpt != null && constantValueOpt.IsIntegral) { uInt64Value = constantValueOpt.UInt64Value; if (uInt64Value <= 1) { flag = true; goto IL_0029; } } flag = false; goto IL_0029; } goto IL_007a; IL_007a: reference = false; return false; IL_0029: if (flag) { reference = uInt64Value == 1; return true; } if (constantValueOpt != null && constantValueOpt.IsBoolean) { bool booleanValue = constantValueOpt.BooleanValue; reference = booleanValue; return true; } char charValue = default(char); if (constantValueOpt != null && constantValueOpt.IsChar) { charValue = constantValueOpt.CharValue; if (charValue == '\0' || charValue == '\u0001') { flag = true; goto IL_006e; } } flag = false; goto IL_006e; IL_006e: if (flag) { reference = charValue == '\u0001'; return true; } goto IL_007a; } } private void EmitNullCoalescingOperator(BoundNullCoalescingOperator expr, bool used) { EmitExpression(expr.LeftOperand, used: true); TypeSymbol typeSymbol = StackMergeType(expr.LeftOperand); if (used) { if (IsVarianceCast(expr.Type, typeSymbol)) { EmitStaticCast(expr.Type, expr.Syntax); typeSymbol = expr.Type; } else if (expr.Type.IsInterfaceType() && !TypeSymbol.Equals(expr.Type, typeSymbol, (TypeCompareKind)0)) { EmitStaticCast(expr.Type, expr.Syntax); } _builder.EmitOpCode(ILOpCode.Dup); } if (expr.Type.IsTypeParameter()) { EmitBox(expr.Type, expr.LeftOperand.Syntax); } object obj = new object(); _builder.EmitBranch(ILOpCode.Brtrue, obj, ILOpCode.Nop); if (used) { _builder.EmitOpCode(ILOpCode.Pop); } EmitExpression(expr.RightOperand, used); if (used) { TypeSymbol typeSymbol2 = StackMergeType(expr.RightOperand); if (IsVarianceCast(expr.Type, typeSymbol2)) { EmitStaticCast(expr.Type, expr.Syntax); typeSymbol2 = expr.Type; } } _builder.MarkLabel(obj); } private TypeSymbol StackMergeType(BoundExpression expr) { if (!expr.Type.IsInterfaceType() && !expr.Type.IsDelegateType()) { return expr.Type; } switch (expr.Kind) { case BoundKind.Conversion: { BoundConversion boundConversion = (BoundConversion)expr; ConversionKind conversionKind = boundConversion.ConversionKind; if (conversionKind.IsImplicitConversion() && conversionKind != ConversionKind.MethodGroup && conversionKind != ConversionKind.NullLiteral && conversionKind != ConversionKind.DefaultLiteral) { return StackMergeType(boundConversion.Operand); } break; } case BoundKind.AssignmentOperator: { BoundAssignmentOperator boundAssignmentOperator = (BoundAssignmentOperator)expr; return StackMergeType(boundAssignmentOperator.Right); } case BoundKind.Sequence: { BoundSequence boundSequence = (BoundSequence)expr; return StackMergeType(boundSequence.Value); } case BoundKind.Local: { BoundLocal boundLocal = (BoundLocal)expr; if (IsStackLocal(boundLocal.LocalSymbol)) { return null; } break; } case BoundKind.Dup: return null; } return expr.Type; } private static bool IsVarianceCast(TypeSymbol to, TypeSymbol from) { if (TypeSymbol.Equals(to, from, (TypeCompareKind)0)) { return false; } if ((object)from == null) { return true; } if (to.IsArray()) { return IsVarianceCast(((ArrayTypeSymbol)to).ElementType, ((ArrayTypeSymbol)from).ElementType); } if (!to.IsDelegateType() || TypeSymbol.Equals(to, from, (TypeCompareKind)0)) { if (to.IsInterfaceType() && from.IsInterfaceType()) { return !from.InterfacesAndTheirBaseInterfacesNoUseSiteDiagnostics.ContainsKey((NamedTypeSymbol)to); } return false; } return true; } private void EmitStaticCast(TypeSymbol to, SyntaxNode syntax) { LocalDefinition val = AllocateTemp(to, syntax, (LocalSlotConstraints)0); _builder.EmitLocalStore(val); _builder.EmitLocalLoad(val); FreeTemp(val); } private void EmitBox(TypeSymbol type, SyntaxNode syntaxNode) { _builder.EmitOpCode(ILOpCode.Box); EmitSymbolToken(type, syntaxNode); } private void EmitCalli(BoundFunctionPointerInvocation ptrInvocation, UseKind useKind) { EmitExpression(ptrInvocation.InvokedExpression, used: true); LocalDefinition val = null; if (ptrInvocation.Arguments.Length > 0) { val = AllocateTemp(ptrInvocation.InvokedExpression.Type, ptrInvocation.Syntax, (LocalSlotConstraints)0); _builder.EmitLocalStore(val); } FunctionPointerMethodSymbol signature = ptrInvocation.FunctionPointer.Signature; EmitArguments(ptrInvocation.Arguments, signature.Parameters, ptrInvocation.ArgumentRefKindsOpt); int callStackBehavior = GetCallStackBehavior(ptrInvocation.FunctionPointer.Signature, ptrInvocation.Arguments); if (val != null) { _builder.EmitLocalLoad(val); FreeTemp(val); } _builder.EmitOpCode(ILOpCode.Calli, callStackBehavior); EmitSignatureToken(ptrInvocation.FunctionPointer, ptrInvocation.Syntax); EmitCallCleanup(ptrInvocation.Syntax, useKind, signature); } private void EmitCallCleanup(SyntaxNode syntax, UseKind useKind, MethodSymbol method) { //IL_0015: 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) if (!method.ReturnsVoid) { EmitPopIfUnused(useKind != UseKind.Unused); } else if ((int)_ilEmitStyle == 0) { _builder.EmitOpCode(ILOpCode.Nop); } if (useKind == UseKind.UsedAsValue && (int)method.RefKind != 0) { EmitLoadIndirect(method.ReturnType, syntax); } else { _ = 2; } } private void EmitLoadFunction(BoundFunctionPointerLoad load, bool used) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 if (!used) { return; } if ((load.TargetMethod.IsAbstract || load.TargetMethod.IsVirtual) && load.TargetMethod.IsStatic) { TypeSymbol constrainedToTypeOpt = load.ConstrainedToTypeOpt; if ((object)constrainedToTypeOpt == null || (int)constrainedToTypeOpt.TypeKind != 11) { throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs", 4073); } _builder.EmitOpCode(ILOpCode.Constrained); EmitSymbolToken(load.ConstrainedToTypeOpt, load.Syntax); } _builder.EmitOpCode(ILOpCode.Ldftn); EmitSymbolToken(load.TargetMethod, load.Syntax, null); } private void EmitUnaryOperatorExpression(BoundUnaryOperator expression, bool used) { UnaryOperatorKind operatorKind = expression.OperatorKind; if (operatorKind.IsChecked()) { EmitUnaryCheckedOperatorExpression(expression, used); return; } if (!used) { EmitExpression(expression.Operand, used: false); return; } if (operatorKind == UnaryOperatorKind.BoolLogicalNegation) { EmitCondExpr(expression.Operand, sense: false); return; } EmitExpression(expression.Operand, used: true); switch (operatorKind.Operator()) { case UnaryOperatorKind.UnaryMinus: _builder.EmitOpCode(ILOpCode.Neg); break; case UnaryOperatorKind.BitwiseComplement: _builder.EmitOpCode(ILOpCode.Not); break; default: throw ExceptionUtilities.UnexpectedValue((object)operatorKind.Operator()); case UnaryOperatorKind.UnaryPlus: break; } } private void EmitBinaryOperatorExpression(BoundBinaryOperator expression, bool used) { BinaryOperatorKind operatorKind = expression.OperatorKind; if (operatorKind.EmitsAsCheckedInstruction()) { EmitBinaryOperator(expression); } else { if (!used && !operatorKind.IsLogical() && !OperatorHasSideEffects(operatorKind)) { EmitExpression(expression.Left, used: false); EmitExpression(expression.Right, used: false); return; } if (IsConditional(operatorKind)) { EmitBinaryCondOperator(expression, sense: true); } else { EmitBinaryOperator(expression); } } EmitPopIfUnused(used); } private void EmitBinaryOperator(BoundBinaryOperator expression) { BoundExpression left = expression.Left; if (left.Kind != BoundKind.BinaryOperator || left.ConstantValueOpt != (ConstantValue)null) { EmitBinaryOperatorSimple(expression); return; } BoundBinaryOperator boundBinaryOperator = (BoundBinaryOperator)left; BinaryOperatorKind operatorKind = boundBinaryOperator.OperatorKind; if (!operatorKind.EmitsAsCheckedInstruction() && IsConditional(operatorKind)) { EmitBinaryOperatorSimple(expression); return; } ArrayBuilder instance = ArrayBuilder.GetInstance(); ArrayBuilderExtensions.Push(instance, expression); do { ArrayBuilderExtensions.Push(instance, boundBinaryOperator); left = boundBinaryOperator.Left; if (left.Kind != BoundKind.BinaryOperator || left.ConstantValueOpt != (ConstantValue)null) { break; } boundBinaryOperator = (BoundBinaryOperator)left; operatorKind = boundBinaryOperator.OperatorKind; } while (operatorKind.EmitsAsCheckedInstruction() || !IsConditional(operatorKind)); EmitExpression(left, used: true); do { boundBinaryOperator = ArrayBuilderExtensions.Pop(instance); EmitExpression(boundBinaryOperator.Right, used: true); bool flag = boundBinaryOperator.OperatorKind.EmitsAsCheckedInstruction(); if (flag) { EmitBinaryCheckedOperatorInstruction(boundBinaryOperator); } else { EmitBinaryOperatorInstruction(boundBinaryOperator); } EmitConversionToEnumUnderlyingType(boundBinaryOperator, flag); } while (instance.Count > 0); instance.Free(); } private void EmitBinaryOperatorSimple(BoundBinaryOperator expression) { EmitExpression(expression.Left, used: true); EmitExpression(expression.Right, used: true); bool flag = expression.OperatorKind.EmitsAsCheckedInstruction(); if (flag) { EmitBinaryCheckedOperatorInstruction(expression); } else { EmitBinaryOperatorInstruction(expression); } EmitConversionToEnumUnderlyingType(expression, flag); } private void EmitBinaryOperatorInstruction(BoundBinaryOperator expression) { switch (expression.OperatorKind.Operator()) { case BinaryOperatorKind.Multiplication: _builder.EmitOpCode(ILOpCode.Mul); break; case BinaryOperatorKind.Addition: _builder.EmitOpCode(ILOpCode.Add); break; case BinaryOperatorKind.Subtraction: _builder.EmitOpCode(ILOpCode.Sub); break; case BinaryOperatorKind.Division: if (IsUnsignedBinaryOperator(expression)) { _builder.EmitOpCode(ILOpCode.Div_un); } else { _builder.EmitOpCode(ILOpCode.Div); } break; case BinaryOperatorKind.Remainder: if (IsUnsignedBinaryOperator(expression)) { _builder.EmitOpCode(ILOpCode.Rem_un); } else { _builder.EmitOpCode(ILOpCode.Rem); } break; case BinaryOperatorKind.LeftShift: _builder.EmitOpCode(ILOpCode.Shl); break; case BinaryOperatorKind.RightShift: if (IsUnsignedBinaryOperator(expression)) { _builder.EmitOpCode(ILOpCode.Shr_un); } else { _builder.EmitOpCode(ILOpCode.Shr); } break; case BinaryOperatorKind.UnsignedRightShift: _builder.EmitOpCode(ILOpCode.Shr_un); break; case BinaryOperatorKind.And: _builder.EmitOpCode(ILOpCode.And); break; case BinaryOperatorKind.Xor: _builder.EmitOpCode(ILOpCode.Xor); break; case BinaryOperatorKind.Or: _builder.EmitOpCode(ILOpCode.Or); break; default: throw ExceptionUtilities.UnexpectedValue((object)expression.OperatorKind.Operator()); } } private void EmitShortCircuitingOperator(BoundBinaryOperator condition, bool sense, bool stopSense, bool stopValue) { object dest = null; EmitCondBranch(condition.Left, ref dest, stopSense); EmitCondExpr(condition.Right, sense); if (dest != null) { object obj = new object(); _builder.EmitBranch(ILOpCode.Br, obj, ILOpCode.Nop); _builder.AdjustStack(-1); _builder.MarkLabel(dest); _builder.EmitBoolConstant(stopValue); _builder.MarkLabel(obj); } } private void EmitBinaryCondOperator(BoundBinaryOperator binOp, bool sense) { bool flag = sense; BinaryOperatorKind binaryOperatorKind = binOp.OperatorKind.OperatorWithLogical(); int num; if (binaryOperatorKind <= BinaryOperatorKind.GreaterThanOrEqual) { if (binaryOperatorKind <= BinaryOperatorKind.NotEqual) { if (binaryOperatorKind != BinaryOperatorKind.Equal) { if (binaryOperatorKind != BinaryOperatorKind.NotEqual) { goto IL_01db; } sense = !sense; } ConstantValue constantValueOpt = binOp.Left.ConstantValueOpt; BoundExpression boundExpression = binOp.Right; if (constantValueOpt == (ConstantValue)null) { constantValueOpt = boundExpression.ConstantValueOpt; boundExpression = binOp.Left; } if (constantValueOpt != (ConstantValue)null) { if (constantValueOpt.IsDefaultValue) { if (!constantValueOpt.IsFloating) { if (sense) { EmitIsNullOrZero(boundExpression, constantValueOpt); } else { EmitIsNotNullOrZero(boundExpression, constantValueOpt); } return; } } else if (constantValueOpt.IsBoolean) { EmitExpression(boundExpression, used: true); EmitIsSense(sense); return; } } EmitBinaryCondOperatorHelper(ILOpCode.Ceq, binOp.Left, binOp.Right, sense); return; } if (binaryOperatorKind != BinaryOperatorKind.GreaterThan) { if (binaryOperatorKind != BinaryOperatorKind.LessThan) { if (binaryOperatorKind != BinaryOperatorKind.GreaterThanOrEqual) { goto IL_01db; } num = 3; sense = !sense; } else { num = 0; } } else { num = 2; } } else { if (binaryOperatorKind > BinaryOperatorKind.Xor) { if (binaryOperatorKind != BinaryOperatorKind.Or) { if (binaryOperatorKind != BinaryOperatorKind.LogicalAnd) { if (binaryOperatorKind != BinaryOperatorKind.LogicalOr) { goto IL_01db; } flag = !flag; } if (!flag) { EmitShortCircuitingOperator(binOp, sense, sense, stopValue: true); } else { EmitShortCircuitingOperator(binOp, sense, !sense, stopValue: false); } } else { EmitBinaryCondOperatorHelper(ILOpCode.Or, binOp.Left, binOp.Right, sense); } return; } if (binaryOperatorKind != BinaryOperatorKind.LessThanOrEqual) { switch (binaryOperatorKind) { case BinaryOperatorKind.And: EmitBinaryCondOperatorHelper(ILOpCode.And, binOp.Left, binOp.Right, sense); return; case BinaryOperatorKind.Xor: if (sense) { EmitBinaryCondOperatorHelper(ILOpCode.Xor, binOp.Left, binOp.Right, sense: true); } else { EmitBinaryCondOperatorHelper(ILOpCode.Ceq, binOp.Left, binOp.Right, sense: true); } return; } goto IL_01db; } num = 1; sense = !sense; } if (IsUnsignedBinaryOperator(binOp)) { num += 4; } else if (IsFloat(binOp.OperatorKind)) { num += 8; } EmitBinaryCondOperatorHelper(s_compOpCodes[num], binOp.Left, binOp.Right, sense); return; IL_01db: throw ExceptionUtilities.UnexpectedValue((object)binOp.OperatorKind.OperatorWithLogical()); } private void EmitIsNotNullOrZero(BoundExpression comparand, ConstantValue nullOrZero) { EmitExpression(comparand, used: true); TypeSymbol type = comparand.Type; if (type.IsReferenceType && !type.IsVerifierReference()) { EmitBox(type, comparand.Syntax); } _builder.EmitConstantValue(nullOrZero); _builder.EmitOpCode(ILOpCode.Cgt_un); } private void EmitIsNullOrZero(BoundExpression comparand, ConstantValue nullOrZero) { EmitExpression(comparand, used: true); TypeSymbol type = comparand.Type; if (type.IsReferenceType && !type.IsVerifierReference()) { EmitBox(type, comparand.Syntax); } _builder.EmitConstantValue(nullOrZero); _builder.EmitOpCode(ILOpCode.Ceq); } private void EmitBinaryCondOperatorHelper(ILOpCode opCode, BoundExpression left, BoundExpression right, bool sense) { EmitExpression(left, used: true); EmitExpression(right, used: true); _builder.EmitOpCode(opCode); EmitIsSense(sense); } private void EmitCondExpr(BoundExpression condition, bool sense) { RemoveNegation(ref condition, ref sense); ConstantValue constantValueOpt = condition.ConstantValueOpt; if (constantValueOpt != (ConstantValue)null) { bool booleanValue = constantValueOpt.BooleanValue; _builder.EmitBoolConstant(booleanValue == sense); return; } if (condition.Kind == BoundKind.BinaryOperator) { BoundBinaryOperator boundBinaryOperator = (BoundBinaryOperator)condition; if (IsConditional(boundBinaryOperator.OperatorKind)) { EmitBinaryCondOperator(boundBinaryOperator, sense); return; } } EmitExpression(condition, used: true); EmitIsSense(sense); } private bool TryEmitComparison(BoundExpression condition, bool sense) { RemoveNegation(ref condition, ref sense); ConstantValue constantValueOpt = condition.ConstantValueOpt; if (constantValueOpt != null) { _builder.EmitBoolConstant(constantValueOpt.BooleanValue == sense); return true; } if (condition is BoundBinaryOperator boundBinaryOperator) { if (boundBinaryOperator.OperatorKind.IsComparison()) { EmitBinaryCondOperator(boundBinaryOperator, sense); return true; } return false; } if (condition is BoundIsOperator isOp) { EmitIsExpression(isOp, used: true, omitBooleanConversion: true); _builder.EmitOpCode(ILOpCode.Ldnull); _builder.EmitOpCode(sense ? ILOpCode.Cgt_un : ILOpCode.Ceq); return true; } EmitExpression(condition, used: true); _builder.EmitOpCode(ILOpCode.Ldc_i4_0); _builder.EmitOpCode(sense ? ILOpCode.Cgt_un : ILOpCode.Ceq); return true; } private static void RemoveNegation(ref BoundExpression condition, ref bool sense) { while (condition is BoundUnaryOperator boundUnaryOperator) { condition = boundUnaryOperator.Operand; sense = !sense; } } private void EmitUnaryCheckedOperatorExpression(BoundUnaryOperator expression, bool used) { UnaryOperatorKind unaryOperatorKind = expression.OperatorKind.OperandTypes(); _builder.EmitOpCode(ILOpCode.Ldc_i4_0); switch (unaryOperatorKind) { case UnaryOperatorKind.Long: _builder.EmitOpCode(ILOpCode.Conv_i8); break; case UnaryOperatorKind.NInt: _builder.EmitOpCode(ILOpCode.Conv_i); break; } EmitExpression(expression.Operand, used: true); _builder.EmitOpCode(ILOpCode.Sub_ovf); EmitPopIfUnused(used); } private void EmitConversionToEnumUnderlyingType(BoundBinaryOperator expression, bool @checked) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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) //IL_00b3: Expected I4, but got Unknown TypeSymbol typeSymbol; switch (expression.OperatorKind.Operator() | expression.OperatorKind.OperandTypes()) { case BinaryOperatorKind.EnumAndUnderlyingAddition: case BinaryOperatorKind.EnumSubtraction: case BinaryOperatorKind.EnumAndUnderlyingSubtraction: typeSymbol = expression.Left.Type; break; case BinaryOperatorKind.EnumAnd: case BinaryOperatorKind.EnumXor: case BinaryOperatorKind.EnumOr: typeSymbol = null; break; case BinaryOperatorKind.UnderlyingAndEnumAddition: case BinaryOperatorKind.UnderlyingAndEnumSubtraction: typeSymbol = expression.Right.Type; break; default: typeSymbol = null; break; } if ((object)typeSymbol != null) { SpecialType specialType = typeSymbol.GetEnumUnderlyingType().SpecialType; switch (specialType - 9) { case 1: _builder.EmitNumericConversion((PrimitiveTypeCode)6, (PrimitiveTypeCode)12, @checked); break; case 0: _builder.EmitNumericConversion((PrimitiveTypeCode)6, (PrimitiveTypeCode)2, @checked); break; case 2: _builder.EmitNumericConversion((PrimitiveTypeCode)6, (PrimitiveTypeCode)5, @checked); break; case 3: _builder.EmitNumericConversion((PrimitiveTypeCode)6, (PrimitiveTypeCode)13, @checked); break; } } } private void EmitBinaryCheckedOperatorInstruction(BoundBinaryOperator expression) { bool flag = IsUnsignedBinaryOperator(expression); switch (expression.OperatorKind.Operator()) { case BinaryOperatorKind.Multiplication: if (flag) { _builder.EmitOpCode(ILOpCode.Mul_ovf_un); } else { _builder.EmitOpCode(ILOpCode.Mul_ovf); } break; case BinaryOperatorKind.Addition: if (flag) { _builder.EmitOpCode(ILOpCode.Add_ovf_un); } else { _builder.EmitOpCode(ILOpCode.Add_ovf); } break; case BinaryOperatorKind.Subtraction: if (flag) { _builder.EmitOpCode(ILOpCode.Sub_ovf_un); } else { _builder.EmitOpCode(ILOpCode.Sub_ovf); } break; default: throw ExceptionUtilities.UnexpectedValue((object)expression.OperatorKind.Operator()); } } private static bool OperatorHasSideEffects(BinaryOperatorKind kind) { BinaryOperatorKind binaryOperatorKind = kind.Operator(); if (binaryOperatorKind == BinaryOperatorKind.Division || binaryOperatorKind == BinaryOperatorKind.Remainder) { return true; } return kind.IsChecked(); } private void EmitIsSense(bool sense) { if (!sense) { _builder.EmitOpCode(ILOpCode.Ldc_i4_0); _builder.EmitOpCode(ILOpCode.Ceq); } } private static bool IsUnsigned(SpecialType type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected I4, but got Unknown switch (type - 10) { case 0: case 2: case 4: case 6: return true; default: return false; } } private static bool IsUnsignedBinaryOperator(BoundBinaryOperator op) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) switch (op.OperatorKind.OperandTypes()) { case BinaryOperatorKind.Enum: case BinaryOperatorKind.EnumAndUnderlying: return IsUnsigned(Binder.GetEnumPromotedType(op.Left.Type.GetEnumUnderlyingType().SpecialType)); case BinaryOperatorKind.UnderlyingAndEnum: return IsUnsigned(Binder.GetEnumPromotedType(op.Right.Type.GetEnumUnderlyingType().SpecialType)); case BinaryOperatorKind.UInt: case BinaryOperatorKind.ULong: case BinaryOperatorKind.NUInt: case BinaryOperatorKind.Pointer: case BinaryOperatorKind.PointerAndInt: case BinaryOperatorKind.PointerAndUInt: case BinaryOperatorKind.PointerAndLong: case BinaryOperatorKind.PointerAndULong: case BinaryOperatorKind.ULongAndPointer: return true; default: return false; } } private static bool IsConditional(BinaryOperatorKind opKind) { switch (opKind.OperatorWithLogical()) { case BinaryOperatorKind.Equal: case BinaryOperatorKind.NotEqual: case BinaryOperatorKind.GreaterThan: case BinaryOperatorKind.LessThan: case BinaryOperatorKind.GreaterThanOrEqual: case BinaryOperatorKind.LessThanOrEqual: case BinaryOperatorKind.LogicalAnd: case BinaryOperatorKind.LogicalOr: return true; case BinaryOperatorKind.And: case BinaryOperatorKind.Xor: case BinaryOperatorKind.Or: return opKind.OperandTypes() == BinaryOperatorKind.Bool; default: return false; } } private static bool IsFloat(BinaryOperatorKind opKind) { BinaryOperatorKind binaryOperatorKind = opKind.OperandTypes(); if ((uint)(binaryOperatorKind - 12) <= 1u) { return true; } return false; } private void EmitStackAllocInitializers(TypeSymbol type, BoundArrayInitialization inits) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_00e7: Unknown result type (might be due to invalid IL or missing references) TypeSymbol type2 = (((int)type.TypeKind == 9) ? ((PointerTypeSymbol)type).PointedAtTypeWithAnnotations : ((NamedTypeSymbol)type).TypeArgumentsWithAnnotationsNoUseSiteDiagnostics[0]).Type; ImmutableArray initializers = inits.Initializers; ArrayInitializerStyle arrayInitializerStyle = ShouldEmitBlockInitializerForStackAlloc(type2, initializers); if (arrayInitializerStyle == ArrayInitializerStyle.Element) { EmitElementStackAllocInitializers(type2, initializers, includeConstants: true); return; } ImmutableArray data = GetRawData(initializers); if (data.All((byte datum) => datum == data[0])) { _builder.EmitOpCode(ILOpCode.Dup); _builder.EmitIntConstant((int)data[0]); _builder.EmitIntConstant(data.Length); _builder.EmitOpCode(ILOpCode.Initblk, -3); if (arrayInitializerStyle == ArrayInitializerStyle.Mixed) { EmitElementStackAllocInitializers(type2, initializers, includeConstants: false); } } else if (SpecialTypeExtensions.SizeInBytes(type2.EnumUnderlyingTypeOrSelf().SpecialType) == 1) { IFieldReference fieldForData = _builder.module.GetFieldForData(data, (ushort)1, inits.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); _builder.EmitOpCode(ILOpCode.Dup); _builder.EmitOpCode(ILOpCode.Ldsflda); _builder.EmitToken((IReference)(object)fieldForData, inits.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag, (RawTokenEncoding)0); _builder.EmitIntConstant(data.Length); _builder.EmitOpCode(ILOpCode.Cpblk, -3); if (arrayInitializerStyle == ArrayInitializerStyle.Mixed) { EmitElementStackAllocInitializers(type2, initializers, includeConstants: false); } } else { EmitElementStackAllocInitializers(type2, initializers, includeConstants: true); } } private ArrayInitializerStyle ShouldEmitBlockInitializerForStackAlloc(TypeSymbol elementType, ImmutableArray inits) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (((CommonPEModuleBuilder)_module).IsEncDelta) { return ArrayInitializerStyle.Element; } if (SpecialTypeExtensions.IsBlittable(elementType.EnumUnderlyingTypeOrSelf().SpecialType)) { int initCount = 0; int constInits = 0; StackAllocInitializerCount(inits, ref initCount, ref constInits); if (initCount > 2) { if (initCount == constInits) { return ArrayInitializerStyle.Block; } int num = Math.Max(3, initCount / 3); if (constInits >= num) { return ArrayInitializerStyle.Mixed; } } } return ArrayInitializerStyle.Element; } private void StackAllocInitializerCount(ImmutableArray inits, ref int initCount, ref int constInits) { if (inits.Length == 0) { return; } ImmutableArray.Enumerator enumerator = inits.GetEnumerator(); while (enumerator.MoveNext()) { BoundExpression current = enumerator.Current; initCount++; if (current.ConstantValueOpt != (ConstantValue)null) { constInits++; } } } private void EmitElementStackAllocInitializers(TypeSymbol elementType, ImmutableArray inits, bool includeConstants) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) int num = 0; int elementTypeSizeInBytes = SpecialTypeExtensions.SizeInBytes(elementType.EnumUnderlyingTypeOrSelf().SpecialType); ImmutableArray.Enumerator enumerator = inits.GetEnumerator(); while (enumerator.MoveNext()) { BoundExpression current = enumerator.Current; if (includeConstants || current.ConstantValueOpt == (ConstantValue)null) { _builder.EmitOpCode(ILOpCode.Dup); EmitPointerElementAccess(current, elementType, elementTypeSizeInBytes, num); EmitExpression(current, used: true); EmitIndirectStore(elementType, current.Syntax); } num++; } } private void EmitPointerElementAccess(BoundExpression init, TypeSymbol elementType, int elementTypeSizeInBytes, int index) { if (index != 0) { if (elementTypeSizeInBytes == 1) { _builder.EmitIntConstant(index); _builder.EmitOpCode(ILOpCode.Add); return; } if (index == 1) { EmitIntConstantOrSizeOf(init, elementType, elementTypeSizeInBytes); _builder.EmitOpCode(ILOpCode.Add); return; } _builder.EmitIntConstant(index); _builder.EmitOpCode(ILOpCode.Conv_i); EmitIntConstantOrSizeOf(init, elementType, elementTypeSizeInBytes); _builder.EmitOpCode(ILOpCode.Mul); _builder.EmitOpCode(ILOpCode.Add); } } private void EmitIntConstantOrSizeOf(BoundExpression init, TypeSymbol elementType, int elementTypeSizeInBytes) { if (elementTypeSizeInBytes == 0) { _builder.EmitOpCode(ILOpCode.Sizeof); EmitSymbolToken(elementType, init.Syntax); } else { _builder.EmitIntConstant(elementTypeSizeInBytes); } } private void EmitStatement(BoundStatement statement) { switch (statement.Kind) { case BoundKind.Block: EmitBlock((BoundBlock)statement); break; case BoundKind.Scope: EmitScope((BoundScope)statement); break; case BoundKind.SequencePoint: EmitSequencePointStatement((BoundSequencePoint)statement); break; case BoundKind.SequencePointWithSpan: EmitSequencePointStatement((BoundSequencePointWithSpan)statement); break; case BoundKind.SavePreviousSequencePoint: EmitSavePreviousSequencePoint((BoundSavePreviousSequencePoint)statement); break; case BoundKind.RestorePreviousSequencePoint: EmitRestorePreviousSequencePoint((BoundRestorePreviousSequencePoint)statement); break; case BoundKind.StepThroughSequencePoint: EmitStepThroughSequencePoint((BoundStepThroughSequencePoint)statement); break; case BoundKind.ExpressionStatement: EmitExpression(((BoundExpressionStatement)statement).Expression, used: false); break; case BoundKind.StatementList: EmitStatementList((BoundStatementList)statement); break; case BoundKind.ReturnStatement: EmitReturnStatement((BoundReturnStatement)statement); break; case BoundKind.GotoStatement: EmitGotoStatement((BoundGotoStatement)statement); break; case BoundKind.LabelStatement: EmitLabelStatement((BoundLabelStatement)statement); break; case BoundKind.ConditionalGoto: EmitConditionalGoto((BoundConditionalGoto)statement); break; case BoundKind.ThrowStatement: EmitThrowStatement((BoundThrowStatement)statement); break; case BoundKind.TryStatement: EmitTryStatement((BoundTryStatement)statement); break; case BoundKind.SwitchDispatch: EmitSwitchDispatch((BoundSwitchDispatch)statement); break; case BoundKind.StateMachineScope: EmitStateMachineScope((BoundStateMachineScope)statement); break; case BoundKind.NoOpStatement: EmitNoOpStatement((BoundNoOpStatement)statement); break; default: throw ExceptionUtilities.UnexpectedValue((object)statement.Kind); } ReleaseExpressionTemps(); } private int EmitStatementAndCountInstructions(BoundStatement statement) { int instructionsEmitted = _builder.InstructionsEmitted; EmitStatement(statement); return _builder.InstructionsEmitted - instructionsEmitted; } private void EmitStatementList(BoundStatementList list) { int i = 0; for (int length = list.Statements.Length; i < length; i++) { EmitStatement(list.Statements[i]); } } private void EmitNoOpStatement(BoundNoOpStatement statement) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) switch (statement.Flavor) { case NoOpStatementFlavor.Default: if ((int)_ilEmitStyle == 0) { _builder.EmitOpCode(ILOpCode.Nop); } break; case NoOpStatementFlavor.AwaitYieldPoint: if (_asyncYieldPoints == null) { _asyncYieldPoints = ArrayBuilder.GetInstance(); _asyncResumePoints = ArrayBuilder.GetInstance(); } _asyncYieldPoints.Add(_builder.AllocateILMarker()); break; case NoOpStatementFlavor.AwaitResumePoint: _asyncResumePoints.Add(_builder.AllocateILMarker()); break; default: throw ExceptionUtilities.UnexpectedValue((object)statement.Flavor); } } private void EmitThrowStatement(BoundThrowStatement node) { EmitThrow(node.ExpressionOpt); } private void EmitThrow(BoundExpression thrown) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 if (thrown != null) { EmitExpression(thrown, used: true); TypeSymbol type = thrown.Type; if ((object)type != null && (int)type.TypeKind == 11) { EmitBox(type, thrown.Syntax); } } _builder.EmitThrow(thrown == null); } private void EmitConditionalGoto(BoundConditionalGoto boundConditionalGoto) { object dest = boundConditionalGoto.Label; EmitCondBranch(boundConditionalGoto.Condition, ref dest, boundConditionalGoto.JumpIfTrue); } private static bool CanPassToBrfalse(TypeSymbol ts) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 if (ts.IsEnumType()) { return true; } PrimitiveTypeCode primitiveTypeCode = ts.PrimitiveTypeCode; if (primitiveTypeCode - 3 > 1) { if ((int)primitiveTypeCode == 18) { return ts.IsReferenceType; } return true; } return false; } private static BoundExpression TryReduce(BoundBinaryOperator condition, ref bool sense) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Invalid comparison between Unknown and I4 BinaryOperatorKind binaryOperatorKind = condition.OperatorKind.Operator(); BoundExpression boundExpression = ((condition.Left.ConstantValueOpt != (ConstantValue)null) ? condition.Left : null); BoundExpression boundExpression2; if (boundExpression != null) { boundExpression2 = condition.Right; } else { boundExpression = ((condition.Right.ConstantValueOpt != (ConstantValue)null) ? condition.Right : null); if (boundExpression == null) { return null; } boundExpression2 = condition.Left; } TypeSymbol type = boundExpression2.Type; if (!CanPassToBrfalse(type)) { return null; } bool num = (int)type.PrimitiveTypeCode == 0; bool isDefaultValue = boundExpression.ConstantValueOpt.IsDefaultValue; if (!num && !isDefaultValue) { return null; } if (isDefaultValue) { sense = !sense; } if (binaryOperatorKind == BinaryOperatorKind.NotEqual) { sense = !sense; } return boundExpression2; } private static ILOpCode CodeForJump(BoundBinaryOperator op, bool sense, out ILOpCode revOpCode) { int num; switch (op.OperatorKind.Operator()) { case BinaryOperatorKind.Equal: revOpCode = ((!sense) ? ILOpCode.Beq : ILOpCode.Bne_un); if (!sense) { return ILOpCode.Bne_un; } return ILOpCode.Beq; case BinaryOperatorKind.NotEqual: revOpCode = ((!sense) ? ILOpCode.Bne_un : ILOpCode.Beq); if (!sense) { return ILOpCode.Beq; } return ILOpCode.Bne_un; case BinaryOperatorKind.LessThan: num = 0; break; case BinaryOperatorKind.LessThanOrEqual: num = 1; break; case BinaryOperatorKind.GreaterThan: num = 2; break; case BinaryOperatorKind.GreaterThanOrEqual: num = 3; break; default: throw ExceptionUtilities.UnexpectedValue((object)op.OperatorKind.Operator()); } if (IsUnsignedBinaryOperator(op)) { num += 8; } else if (IsFloat(op.OperatorKind)) { num += 16; } int num2 = num; if (!sense) { num += 4; } else { num2 += 4; } revOpCode = s_condJumpOpCodes[num2]; return s_condJumpOpCodes[num]; } private void EmitCondBranch(BoundExpression condition, ref object dest, bool sense) { _recursionDepth++; if (_recursionDepth > 1) { StackGuard.EnsureSufficientExecutionStack(_recursionDepth); EmitCondBranchCore(condition, ref dest, sense); } else { EmitCondBranchCoreWithStackGuard(condition, ref dest, sense); } _recursionDepth--; } private void EmitCondBranchCoreWithStackGuard(BoundExpression condition, ref object dest, bool sense) { try { EmitCondBranchCore(condition, ref dest, sense); } catch (InsufficientExecutionStackException) { _diagnostics.Add(ErrorCode.ERR_InsufficientStack, BoundTreeVisitor.CancelledByStackGuardException.GetTooLongOrComplexExpressionErrorLocation(condition)); throw new EmitCancelledException(); } } private void EmitCondBranchCore(BoundExpression condition, ref object dest, bool sense) { BoundBinaryOperator boundBinaryOperator2 = default(BoundBinaryOperator); ILOpCode iLOpCode; while (true) { if (condition.ConstantValueOpt != (ConstantValue)null) { if (condition.ConstantValueOpt.IsDefaultValue != sense) { dest = dest ?? new object(); _builder.EmitBranch(ILOpCode.Br, dest, ILOpCode.Nop); } return; } switch (condition.Kind) { case BoundKind.BinaryOperator: { BoundBinaryOperator boundBinaryOperator = (BoundBinaryOperator)condition; BinaryOperatorKind binaryOperatorKind = boundBinaryOperator.OperatorKind.OperatorWithLogical(); if ((binaryOperatorKind == BinaryOperatorKind.LogicalAnd || binaryOperatorKind == BinaryOperatorKind.LogicalOr) ? true : false) { ArrayBuilder<(BoundExpression, StrongBox, bool)> instance = ArrayBuilder<(BoundExpression, StrongBox, bool)>.GetInstance(); StrongBox strongBox = new StrongBox(dest); ArrayBuilderExtensions.Push<(BoundExpression, StrongBox, bool)>(instance, ((BoundExpression)boundBinaryOperator, strongBox, sense)); (BoundExpression, StrongBox, bool) tuple; while (true) { tuple = ArrayBuilderExtensions.Pop<(BoundExpression, StrongBox, bool)>(instance); if (tuple.Item1 == null) { object value = tuple.Item2.Value; if (value != null) { _builder.MarkLabel(value); } } else { int num; if (tuple.Item1.ConstantValueOpt == null) { boundBinaryOperator2 = tuple.Item1 as BoundBinaryOperator; num = ((boundBinaryOperator2 != null) ? 1 : 0); } else { num = 0; } bool flag = (byte)num != 0; if (flag) { binaryOperatorKind = boundBinaryOperator2.OperatorKind.OperatorWithLogical(); bool flag2 = ((binaryOperatorKind == BinaryOperatorKind.LogicalAnd || binaryOperatorKind == BinaryOperatorKind.LogicalOr) ? true : false); flag = flag2; } if (flag) { if ((boundBinaryOperator2.OperatorKind.OperatorWithLogical() == BinaryOperatorKind.LogicalOr) ? (!tuple.Item3) : tuple.Item3) { StrongBox item = new StrongBox(); ArrayBuilderExtensions.Push<(BoundExpression, StrongBox, bool)>(instance, ((BoundExpression)null, item, true)); ArrayBuilderExtensions.Push<(BoundExpression, StrongBox, bool)>(instance, (boundBinaryOperator2.Right, tuple.Item2, tuple.Item3)); ArrayBuilderExtensions.Push<(BoundExpression, StrongBox, bool)>(instance, (boundBinaryOperator2.Left, item, !tuple.Item3)); } else { ArrayBuilderExtensions.Push<(BoundExpression, StrongBox, bool)>(instance, (boundBinaryOperator2.Right, tuple.Item2, tuple.Item3)); ArrayBuilderExtensions.Push<(BoundExpression, StrongBox, bool)>(instance, (boundBinaryOperator2.Left, tuple.Item2, tuple.Item3)); } } else { if (instance.Count == 0 && strongBox == tuple.Item2) { break; } EmitCondBranch(tuple.Item1, ref tuple.Item2.Value, tuple.Item3); } } if (instance.Count == 0) { dest = strongBox.Value; instance.Free(); return; } } condition = tuple.Item1; sense = tuple.Item3; dest = strongBox.Value; instance.Free(); continue; } binaryOperatorKind = boundBinaryOperator.OperatorKind.OperatorWithLogical(); if (binaryOperatorKind <= BinaryOperatorKind.LessThan) { if (binaryOperatorKind <= BinaryOperatorKind.NotEqual) { if (binaryOperatorKind != BinaryOperatorKind.Equal && binaryOperatorKind != BinaryOperatorKind.NotEqual) { break; } BoundExpression boundExpression = TryReduce(boundBinaryOperator, ref sense); if (boundExpression != null) { condition = boundExpression; continue; } } else if (binaryOperatorKind != BinaryOperatorKind.GreaterThan && binaryOperatorKind != BinaryOperatorKind.LessThan) { break; } } else { if (binaryOperatorKind > BinaryOperatorKind.LessThanOrEqual) { if (binaryOperatorKind == BinaryOperatorKind.LogicalAnd || binaryOperatorKind == BinaryOperatorKind.LogicalOr) { throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/CodeGen/EmitStatement.cs", 496); } break; } if (binaryOperatorKind != BinaryOperatorKind.GreaterThanOrEqual && binaryOperatorKind != BinaryOperatorKind.LessThanOrEqual) { break; } } EmitExpression(boundBinaryOperator.Left, used: true); EmitExpression(boundBinaryOperator.Right, used: true); iLOpCode = CodeForJump(boundBinaryOperator, sense, out var revOpCode); dest = dest ?? new object(); _builder.EmitBranch(iLOpCode, dest, revOpCode); return; } case BoundKind.LoweredConditionalAccess: { BoundLoweredConditionalAccess boundLoweredConditionalAccess = (BoundLoweredConditionalAccess)condition; BoundExpression receiver = boundLoweredConditionalAccess.Receiver; if (!receiver.Type.IsReferenceType || LocalRewriter.CanChangeValueBetweenReads(receiver, localsMayBeAssignedOrCaptured: false) || (receiver.Kind == BoundKind.Local && IsStackLocal(((BoundLocal)receiver).LocalSymbol))) { break; } BoundExpression? whenNullOpt = boundLoweredConditionalAccess.WhenNullOpt; if (whenNullOpt != null && !whenNullOpt.IsDefaultValue()) { break; } if (sense) { object dest2 = null; EmitCondBranch(receiver, ref dest2, sense: false); EmitReceiverRef(receiver, Binder.AddressKind.ReadOnly); EmitCondBranch(boundLoweredConditionalAccess.WhenNotNull, ref dest, sense: true); if (dest2 != null) { _builder.MarkLabel(dest2); } return; } EmitCondBranch(receiver, ref dest, sense: false); EmitReceiverRef(receiver, Binder.AddressKind.ReadOnly); condition = boundLoweredConditionalAccess.WhenNotNull; continue; } case BoundKind.UnaryOperator: { BoundUnaryOperator boundUnaryOperator = (BoundUnaryOperator)condition; if (boundUnaryOperator.OperatorKind == UnaryOperatorKind.BoolLogicalNegation) { sense = !sense; condition = boundUnaryOperator.Operand; continue; } break; } case BoundKind.IsOperator: { BoundIsOperator boundIsOperator = (BoundIsOperator)condition; BoundExpression operand = boundIsOperator.Operand; EmitExpression(operand, used: true); if (!operand.Type.IsVerifierReference()) { EmitBox(operand.Type, operand.Syntax); } _builder.EmitOpCode(ILOpCode.Isinst); EmitSymbolToken(boundIsOperator.TargetType.Type, boundIsOperator.TargetType.Syntax); iLOpCode = (sense ? ILOpCode.Brtrue : ILOpCode.Brfalse); dest = dest ?? new object(); _builder.EmitBranch(iLOpCode, dest, ILOpCode.Nop); return; } case BoundKind.Sequence: { BoundSequence sequence = (BoundSequence)condition; EmitSequenceCondBranch(sequence, ref dest, sense); return; } } break; } EmitExpression(condition, used: true); TypeSymbol type = condition.Type; if (type.IsReferenceType && !type.IsVerifierReference()) { EmitBox(type, condition.Syntax); } iLOpCode = (sense ? ILOpCode.Brtrue : ILOpCode.Brfalse); dest = dest ?? new object(); _builder.EmitBranch(iLOpCode, dest, ILOpCode.Nop); } private void EmitSequenceCondBranch(BoundSequence sequence, ref object dest, bool sense) { DefineLocals(sequence); EmitSideEffects(sequence); EmitCondBranch(sequence.Value, ref dest, sense); FreeLocals(sequence); } private void EmitLabelStatement(BoundLabelStatement boundLabelStatement) { _builder.MarkLabel((object)boundLabelStatement.Label); } private void EmitGotoStatement(BoundGotoStatement boundGotoStatement) { _builder.EmitBranch(ILOpCode.Br, (object)boundGotoStatement.Label, ILOpCode.Nop); } private bool IsLastBlockInMethod(BoundBlock block) { if (_boundBody == block) { return true; } if (_boundBody is BoundStatementList boundStatementList && boundStatementList.Statements.LastOrDefault() == block) { return true; } return false; } private void EmitBlock(BoundBlock block) { if (block.Instrumentation != null) { EmitInstrumentedBlock(block.Instrumentation, block); } else { EmitUninstrumentedBlock(block); } } private void EmitInstrumentedBlock(BoundBlockInstrumentation instrumentation, BoundBlock block) { _builder.OpenLocalScope((ScopeType)0, (ITypeReference)null); DefineLocal(instrumentation.Local, block.Syntax); if (_emitPdbSequencePoints) { EmitHiddenSequencePoint(); } EmitStatement(instrumentation.Prologue); _builder.OpenLocalScope((ScopeType)1, (ITypeReference)null); _builder.OpenLocalScope((ScopeType)2, (ITypeReference)null); EmitUninstrumentedBlock(block); _builder.CloseLocalScope(); _builder.OpenLocalScope((ScopeType)5, (ITypeReference)null); if (_emitPdbSequencePoints) { EmitHiddenSequencePoint(); } EmitStatement(instrumentation.Epilogue); _builder.CloseLocalScope(); _builder.CloseLocalScope(); FreeLocal(instrumentation.Local); _builder.CloseLocalScope(); } private void EmitUninstrumentedBlock(BoundBlock block) { bool flag = !block.Locals.IsEmpty; if (flag) { _builder.OpenLocalScope((ScopeType)0, (ITypeReference)null); ImmutableArray.Enumerator enumerator = block.Locals.GetEnumerator(); while (enumerator.MoveNext()) { LocalSymbol current = enumerator.Current; ImmutableArray declaringSyntaxReferences = current.DeclaringSyntaxReferences; DefineLocal(current, (SyntaxNode)(object)((!declaringSyntaxReferences.IsEmpty) ? ((CSharpSyntaxNode)(object)declaringSyntaxReferences[0].GetSyntax(default(CancellationToken))) : ((CSharpSyntaxNode)(object)block.Syntax))); } } EmitStatements(block.Statements); if (_indirectReturnState == IndirectReturnState.Needed && IsLastBlockInMethod(block)) { if (block.Instrumentation != null) { _builder.EmitBranch(ILOpCode.Br, s_returnLabel, ILOpCode.Nop); } else { HandleReturn(); } } if (flag) { ImmutableArray.Enumerator enumerator = block.Locals.GetEnumerator(); while (enumerator.MoveNext()) { LocalSymbol current2 = enumerator.Current; FreeLocal(current2); } _builder.CloseLocalScope(); } } private void EmitStatements(ImmutableArray statements) { ImmutableArray.Enumerator enumerator = statements.GetEnumerator(); while (enumerator.MoveNext()) { BoundStatement current = enumerator.Current; EmitStatement(current); } } private void EmitScope(BoundScope block) { _builder.OpenLocalScope((ScopeType)0, (ITypeReference)null); ImmutableArray.Enumerator enumerator = block.Locals.GetEnumerator(); while (enumerator.MoveNext()) { LocalSymbol current = enumerator.Current; if (!current.IsConst && !IsStackLocal(current)) { _builder.AddLocalToScope(_builder.LocalSlotManager.GetLocal((ILocalSymbolInternal)(object)current)); } } EmitStatements(block.Statements); _builder.CloseLocalScope(); } private void EmitStateMachineScope(BoundStateMachineScope scope) { _builder.OpenLocalScope((ScopeType)7, (ITypeReference)null); ImmutableArray.Enumerator enumerator = scope.Fields.GetEnumerator(); while (enumerator.MoveNext()) { StateMachineFieldSymbol current = enumerator.Current; if (current.SlotIndex >= 0) { _builder.DefineUserDefinedStateMachineHoistedLocal(current.SlotIndex); } } EmitStatement(scope.Statement); _builder.CloseLocalScope(); } private bool ShouldUseIndirectReturn() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if ((int)_ilEmitStyle == 0 && _method.GenerateDebugInfo) { SyntaxNode methodBodySyntaxOpt = _methodBodySyntaxOpt; if (methodBodySyntaxOpt != null && methodBodySyntaxOpt.IsKind(SyntaxKind.Block)) { return true; } } return _builder.InExceptionHandler; } private bool CanHandleReturnLabel(BoundReturnStatement boundReturnStatement) { if (boundReturnStatement.WasCompilerGenerated) { if (!boundReturnStatement.Syntax.IsKind(SyntaxKind.Block)) { MethodSymbol method = _method; if ((object)method == null || !method.IsImplicitConstructor) { goto IL_003d; } } return !_builder.InExceptionHandler; } goto IL_003d; IL_003d: return false; } private void EmitReturnStatement(BoundReturnStatement boundReturnStatement) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 BoundExpression expressionOpt = boundReturnStatement.ExpressionOpt; if ((int)boundReturnStatement.RefKind == 0) { EmitExpression(expressionOpt, used: true); } else { EmitAddress(expressionOpt, ((int)_method.RefKind == 3) ? Binder.AddressKind.ReadOnlyStrict : Binder.AddressKind.Writeable); } if (ShouldUseIndirectReturn()) { if (expressionOpt != null) { _builder.EmitLocalStore(LazyReturnTemp); } if (_indirectReturnState != IndirectReturnState.Emitted && CanHandleReturnLabel(boundReturnStatement)) { HandleReturn(); return; } _builder.EmitBranch(ILOpCode.Br, s_returnLabel, ILOpCode.Nop); if (_indirectReturnState == IndirectReturnState.NotNeeded) { _indirectReturnState = IndirectReturnState.Needed; } } else if (_indirectReturnState == IndirectReturnState.Needed && CanHandleReturnLabel(boundReturnStatement)) { if (expressionOpt != null) { _builder.EmitLocalStore(LazyReturnTemp); } HandleReturn(); } else { if (expressionOpt != null) { ((PEModuleBuilder)_module).Translate(expressionOpt.Type, boundReturnStatement.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); } _builder.EmitRet(expressionOpt == null); } } private void EmitTryStatement(BoundTryStatement statement, bool emitCatchesOnly = false) { bool num = !emitCatchesOnly && statement.CatchBlocks.Length > 0 && statement.FinallyBlockOpt != null; _builder.OpenLocalScope((ScopeType)1, (ITypeReference)null); _builder.OpenLocalScope((ScopeType)2, (ITypeReference)null); _tryNestingLevel++; if (num) { EmitTryStatement(statement, emitCatchesOnly: true); } else { EmitBlock(statement.TryBlock); } _tryNestingLevel--; _builder.CloseLocalScope(); if (!num) { ImmutableArray.Enumerator enumerator = statement.CatchBlocks.GetEnumerator(); while (enumerator.MoveNext()) { BoundCatchBlock current = enumerator.Current; EmitCatchBlock(current); } } if (!emitCatchesOnly && statement.FinallyBlockOpt != null) { _builder.OpenLocalScope((ScopeType)(statement.PreferFaultHandler ? 6 : 5), (ITypeReference)null); EmitBlock(statement.FinallyBlockOpt); _builder.CloseLocalScope(); _builder.CloseLocalScope(); if (statement.PreferFaultHandler) { BoundBlock block = FinallyCloner.MakeFinallyClone(statement); EmitBlock(block); } } else { _builder.CloseLocalScope(); } } private void EmitCatchBlock(BoundCatchBlock catchBlock) { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) object obj = null; _builder.AdjustStack(1); if (catchBlock.ExceptionFilterOpt == null) { ITypeReference obj2; if ((object)catchBlock.ExceptionTypeOpt == null) { ITypeReference specialType = (ITypeReference)(object)((PEModuleBuilder)_module).GetSpecialType((SpecialType)1, catchBlock.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); obj2 = specialType; } else { obj2 = ((PEModuleBuilder)_module).Translate(catchBlock.ExceptionTypeOpt, catchBlock.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); } ITypeReference val = obj2; _builder.OpenLocalScope((ScopeType)3, val); RecordAsyncCatchHandlerOffset(catchBlock); if (_emitPdbSequencePoints && catchBlock.Syntax is CatchClauseSyntax catchClauseSyntax) { TextSpan span; if (catchClauseSyntax.Declaration == null) { SyntaxToken catchKeyword = catchClauseSyntax.CatchKeyword; span = ((SyntaxToken)(ref catchKeyword)).Span; } else { int spanStart = ((SyntaxNode)catchClauseSyntax).SpanStart; TextSpan span2 = ((SyntaxNode)catchClauseSyntax.Declaration).Span; span = TextSpan.FromBounds(spanStart, ((TextSpan)(ref span2)).End); } EmitSequencePoint(catchBlock.SyntaxTree, span); } } else { _builder.OpenLocalScope((ScopeType)4, (ITypeReference)null); RecordAsyncCatchHandlerOffset(catchBlock); object obj3 = new object(); obj = new object(); if ((object)catchBlock.ExceptionTypeOpt != null) { ITypeReference val2 = ((PEModuleBuilder)_module).Translate(catchBlock.ExceptionTypeOpt, catchBlock.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); _builder.EmitOpCode(ILOpCode.Isinst); _builder.EmitToken((IReference)(object)val2, catchBlock.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag, (RawTokenEncoding)0); _builder.EmitOpCode(ILOpCode.Dup); _builder.EmitBranch(ILOpCode.Brtrue, obj3, ILOpCode.Nop); _builder.EmitOpCode(ILOpCode.Pop); _builder.EmitIntConstant(0); _builder.EmitBranch(ILOpCode.Br, obj, ILOpCode.Nop); } _builder.MarkLabel(obj3); } ImmutableArray.Enumerator enumerator = catchBlock.Locals.GetEnumerator(); while (enumerator.MoveNext()) { LocalSymbol current = enumerator.Current; ImmutableArray declaringSyntaxReferences = current.DeclaringSyntaxReferences; SyntaxNode syntaxNode = (SyntaxNode)(object)((!declaringSyntaxReferences.IsEmpty) ? ((CSharpSyntaxNode)(object)declaringSyntaxReferences[0].GetSyntax(default(CancellationToken))) : ((CSharpSyntaxNode)(object)catchBlock.Syntax)); DefineLocal(current, syntaxNode); } BoundExpression exceptionSourceOpt = catchBlock.ExceptionSourceOpt; if (exceptionSourceOpt != null) { if (!exceptionSourceOpt.Type.IsVerifierReference()) { _builder.EmitOpCode(ILOpCode.Unbox_any); EmitSymbolToken(exceptionSourceOpt.Type, exceptionSourceOpt.Syntax); } BoundExpression boundExpression = exceptionSourceOpt; while (boundExpression.Kind == BoundKind.Sequence) { BoundSequence boundSequence = (BoundSequence)boundExpression; EmitSideEffects(boundSequence); boundExpression = boundSequence.Value; } switch (boundExpression.Kind) { case BoundKind.Local: { BoundLocal boundLocal = (BoundLocal)boundExpression; if (!IsStackLocal(boundLocal.LocalSymbol)) { _builder.EmitLocalStore(GetLocal(boundLocal)); } break; } case BoundKind.FieldAccess: { BoundFieldAccess boundFieldAccess = (BoundFieldAccess)boundExpression; if (boundFieldAccess.FieldSymbol is StateMachineFieldSymbol { SlotIndex: >=0 } stateMachineFieldSymbol) { _builder.DefineUserDefinedStateMachineHoistedLocal(stateMachineFieldSymbol.SlotIndex); } LocalDefinition val3 = AllocateTemp(boundExpression.Type, boundExpression.Syntax, (LocalSlotConstraints)0); _builder.EmitLocalStore(val3); EmitReceiverRef(boundFieldAccess.ReceiverOpt, Binder.AddressKind.Writeable); _builder.EmitLocalLoad(val3); FreeTemp(val3); EmitFieldStore(boundFieldAccess, refAssign: false); break; } default: throw ExceptionUtilities.UnexpectedValue((object)boundExpression.Kind); } } else { _builder.EmitOpCode(ILOpCode.Pop); } if (catchBlock.ExceptionFilterPrologueOpt != null) { EmitStatements(catchBlock.ExceptionFilterPrologueOpt.Statements); } if (catchBlock.ExceptionFilterOpt != null) { EmitCondExpr(catchBlock.ExceptionFilterOpt, sense: true); _builder.EmitIntConstant(0); _builder.EmitOpCode(ILOpCode.Cgt_un); _builder.MarkLabel(obj); _builder.MarkFilterConditionEnd(); _builder.EmitOpCode(ILOpCode.Pop); } EmitBlock(catchBlock.Body); _builder.CloseLocalScope(); } private void RecordAsyncCatchHandlerOffset(BoundCatchBlock catchBlock) { if (catchBlock.IsSynthesizedAsyncCatchAll) { _asyncCatchHandlerOffset = _builder.AllocateILMarker(); } } private void EmitSwitchDispatch(BoundSwitchDispatch dispatch) { EmitSwitchHeader(dispatch.Expression, dispatch.Cases.Select<(ConstantValue, LabelSymbol), KeyValuePair>(((ConstantValue value, LabelSymbol label) p) => new KeyValuePair(p.value, p.label)).ToArray(), dispatch.DefaultLabel, dispatch.LengthBasedStringSwitchDataOpt); } private void EmitSwitchHeader(BoundExpression expression, KeyValuePair[] switchCaseLabels, LabelSymbol fallThroughLabel, LengthBasedStringSwitchData lengthBasedSwitchStringJumpTableOpt) { //IL_0076: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Invalid comparison between Unknown and I4 //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) LocalDefinition val = null; BoundSequence boundSequence = null; if (expression.Kind == BoundKind.Sequence) { boundSequence = (BoundSequence)expression; DefineLocals(boundSequence); EmitSideEffects(boundSequence); expression = boundSequence.Value; } if (expression.Kind == BoundKind.SequencePointExpression) { BoundSequencePointExpression boundSequencePointExpression = (BoundSequencePointExpression)expression; EmitSequencePoint(boundSequencePointExpression); expression = boundSequencePointExpression.Expression; } BoundKind kind = expression.Kind; LocalOrParameter val2; if (kind != BoundKind.Local) { if (kind == BoundKind.Parameter) { BoundParameter boundParameter = (BoundParameter)expression; if ((int)boundParameter.ParameterSymbol.RefKind == 0) { val2 = LocalOrParameter.op_Implicit(ParameterSlot(boundParameter)); goto IL_00eb; } } } else { LocalSymbol localSymbol = ((BoundLocal)expression).LocalSymbol; if ((int)localSymbol.RefKind == 0 && !IsStackLocal(localSymbol)) { val2 = LocalOrParameter.op_Implicit(GetLocal(localSymbol)); goto IL_00eb; } } EmitExpression(expression, used: true); val = AllocateTemp(expression.Type, expression.Syntax, (LocalSlotConstraints)0); _builder.EmitLocalStore(val); val2 = LocalOrParameter.op_Implicit(val); goto IL_00eb; IL_00eb: if ((int)expression.Type.SpecialType == 20 || expression.Type.IsSpanOrReadOnlySpanChar()) { if (lengthBasedSwitchStringJumpTableOpt == null) { EmitStringSwitchJumpTable(switchCaseLabels, fallThroughLabel, val2, expression.Syntax, expression.Type); } else { EmitLengthBasedStringSwitchJumpTable(lengthBasedSwitchStringJumpTableOpt, fallThroughLabel, val2, expression.Syntax, expression.Type); } } else { _builder.EmitIntegerSwitchJumpTable(switchCaseLabels, (object)fallThroughLabel, val2, expression.Type.EnumUnderlyingTypeOrSelf().PrimitiveTypeCode); } if (val != null) { FreeTemp(val); } if (boundSequence != null) { FreeLocals(boundSequence); } } private void EmitLengthBasedStringSwitchJumpTable(LengthBasedStringSwitchData lengthBasedSwitchData, LabelSymbol fallThroughLabel, LocalOrParameter keyTemp, SyntaxNode syntaxNode, TypeSymbol keyType) { //IL_0054: 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_006e: Unknown result type (might be due to invalid IL or missing references) bool flag = keyType.IsSpanChar(); bool flag2 = keyType.IsReadOnlySpanChar(); bool isSpanOrReadOnlySpan = flag || flag2; IMethodReference indexerRef = GetIndexerRef(syntaxNode, keyType, flag2, isSpanOrReadOnlySpan); IMethodReference lengthMethodRef = GetLengthMethodRef(syntaxNode, keyType, flag2, isSpanOrReadOnlySpan); emitLengthDispatch(lengthBasedSwitchData, keyTemp, fallThroughLabel, syntaxNode); emitCharDispatches(lengthBasedSwitchData, keyTemp, fallThroughLabel, syntaxNode); emitFinalDispatches(lengthBasedSwitchData, keyTemp, keyType, fallThroughLabel, syntaxNode); void emitCharDispatches(LengthBasedStringSwitchData lengthBasedSwitchInfo, LocalOrParameter val3, LabelSymbol labelSymbol, SyntaxNode val) { //IL_006c: 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_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) NamedTypeSymbol specialType = Binder.GetSpecialType(((PEModuleBuilder)_module).Compilation, (SpecialType)8, val, _diagnostics); LocalDefinition val2 = AllocateTemp(specialType, val, (LocalSlotConstraints)0); ImmutableArray.Enumerator enumerator = lengthBasedSwitchInfo.CharBasedJumpTables.GetEnumerator(); while (enumerator.MoveNext()) { LengthBasedStringSwitchData.CharJumpTable current = enumerator.Current; _builder.MarkLabel((object)current.Label); if (isSpanOrReadOnlySpan) { _builder.EmitLoadAddress(val3); } else { _builder.EmitLoad(val3); } _builder.EmitIntConstant(current.SelectedCharPosition); _builder.EmitOpCode(ILOpCode.Call, -1); emitMethodRef(indexerRef); if (isSpanOrReadOnlySpan) { _builder.EmitOpCode(ILOpCode.Ldind_u2); } _builder.EmitLocalStore(val2); _builder.EmitIntegerSwitchJumpTable(current.CharCaseLabels.Select<(char, LabelSymbol), KeyValuePair>(((char value, LabelSymbol label) p) => new KeyValuePair(ConstantValue.Create(p.value), p.label)).ToArray(), (object)labelSymbol, LocalOrParameter.op_Implicit(val2), specialType.PrimitiveTypeCode); } FreeTemp(val2); } void emitFinalDispatches(LengthBasedStringSwitchData lengthBasedSwitchInfo, LocalOrParameter key, TypeSymbol keyType2, LabelSymbol fallThroughLabel2, SyntaxNode syntaxNode2) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) ImmutableArray.Enumerator enumerator = lengthBasedSwitchInfo.StringBasedJumpTables.GetEnumerator(); while (enumerator.MoveNext()) { LengthBasedStringSwitchData.StringJumpTable current = enumerator.Current; _builder.MarkLabel((object)current.Label); EmitStringSwitchJumpTable(current.StringCaseLabels.Select<(string, LabelSymbol), KeyValuePair>(((string value, LabelSymbol label) p) => new KeyValuePair(ConstantValue.Create(p.value), p.label)).ToArray(), fallThroughLabel2, key, syntaxNode2, keyType2); } } void emitLengthDispatch(LengthBasedStringSwitchData lengthBasedSwitchInfo, LocalOrParameter val, LabelSymbol labelSymbol, SyntaxNode val2) { //IL_000f: 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) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) if (!isSpanOrReadOnlySpan) { _builder.EmitLoad(val); _builder.EmitBranch(ILOpCode.Brfalse, (object)(lengthBasedSwitchInfo.LengthBasedJumpTable.NullCaseLabel ?? labelSymbol), ILOpCode.Brtrue); } NamedTypeSymbol specialType = Binder.GetSpecialType(((PEModuleBuilder)_module).Compilation, (SpecialType)13, val2, _diagnostics); LocalDefinition val3 = AllocateTemp(specialType, val2, (LocalSlotConstraints)0); if (isSpanOrReadOnlySpan) { _builder.EmitLoadAddress(val); } else { _builder.EmitLoad(val); } _builder.EmitOpCode(ILOpCode.Call, 0); emitMethodRef(lengthMethodRef); _builder.EmitLocalStore(val3); _builder.EmitIntegerSwitchJumpTable(lengthBasedSwitchInfo.LengthBasedJumpTable.LengthCaseLabels.Select<(int, LabelSymbol), KeyValuePair>(((int value, LabelSymbol label) p) => new KeyValuePair(ConstantValue.Create(p.value), p.label)).ToArray(), (object)labelSymbol, LocalOrParameter.op_Implicit(val3), specialType.PrimitiveTypeCode); FreeTemp(val3); } void emitMethodRef(IMethodReference val) { DiagnosticBag instance = DiagnosticBag.GetInstance(); _builder.EmitToken((ISignature)(object)val, (SyntaxNode)null, instance); instance.Free(); } } private void EmitStringSwitchJumpTable(KeyValuePair[] switchCaseLabels, LabelSymbol fallThroughLabel, LocalOrParameter key, SyntaxNode syntaxNode, TypeSymbol keyType) { //IL_000e: 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) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Expected O, but got Unknown //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) bool flag = keyType.IsSpanChar(); bool flag2 = keyType.IsReadOnlySpanChar(); bool isSpanOrReadOnlySpan = flag || flag2; LocalDefinition val = null; if (SwitchStringJumpTableEmitter.ShouldGenerateHashTableSwitch(switchCaseLabels.Length)) { IReference method = (IReference)(object)((PEModuleBuilder)_module).GetPrivateImplClass(syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag).GetMethod((!isSpanOrReadOnlySpan) ? "ComputeStringHash" : (flag2 ? "ComputeReadOnlySpanHash" : "ComputeSpanHash")); if (method != null) { _builder.EmitLoad(key); _builder.EmitOpCode(ILOpCode.Call, 0); _builder.EmitToken(method, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag, (RawTokenEncoding)0); NamedTypeSymbol specialType = Binder.GetSpecialType(((PEModuleBuilder)_module).Compilation, (SpecialType)14, syntaxNode, _diagnostics); val = AllocateTemp(specialType, syntaxNode, (LocalSlotConstraints)0); _builder.EmitLocalStore(val); } } IMethodReference stringEqualityMethodRef = null; IMethodReference sequenceEqualsMethodRef = null; IMethodReference asSpanMethodRef = null; if (isSpanOrReadOnlySpan) { MethodSymbol methodSymbol = ((MethodSymbol)Binder.GetWellKnownTypeMember(((PEModuleBuilder)_module).Compilation, (WellKnownMember)(flag2 ? 474 : 473), _diagnostics, null, syntaxNode)).Construct(Binder.GetSpecialType(((PEModuleBuilder)_module).Compilation, (SpecialType)8, syntaxNode, _diagnostics)); sequenceEqualsMethodRef = _module.Translate(methodSymbol, null, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); MethodSymbol methodSymbol2 = (MethodSymbol)Binder.GetWellKnownTypeMember(((PEModuleBuilder)_module).Compilation, (WellKnownMember)475, _diagnostics, null, syntaxNode); asSpanMethodRef = _module.Translate(methodSymbol2, null, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); } else { MethodSymbol methodSymbol3 = ((PEModuleBuilder)_module).Compilation.GetSpecialTypeMember((SpecialMember)9) as MethodSymbol; stringEqualityMethodRef = _module.Translate(methodSymbol3, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); } IMethodReference lengthMethodRef = GetLengthMethodRef(syntaxNode, keyType, flag2, isSpanOrReadOnlySpan); EmitStringCompareAndBranch val2 = (EmitStringCompareAndBranch)delegate(LocalOrParameter keyArg, ConstantValue stringConstant, object targetLabel) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0114: 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) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) if (stringConstant == ConstantValue.Null) { _builder.EmitLoad(keyArg); _builder.EmitBranch(ILOpCode.Brfalse, targetLabel, ILOpCode.Brtrue); } else if (stringConstant.StringValue.Length == 0 && lengthMethodRef != null) { object obj3 = new object(); if (isSpanOrReadOnlySpan) { _builder.EmitLoadAddress(keyArg); } else { _builder.EmitLoad(keyArg); _builder.EmitBranch(ILOpCode.Brfalse, obj3, ILOpCode.Brtrue); _builder.EmitLoad(keyArg); } _builder.EmitOpCode(ILOpCode.Call, 0); DiagnosticBag instance = DiagnosticBag.GetInstance(); _builder.EmitToken((ISignature)(object)lengthMethodRef, (SyntaxNode)null, instance); instance.Free(); _builder.EmitBranch(ILOpCode.Brfalse, targetLabel, ILOpCode.Brtrue); _builder.MarkLabel(obj3); } else if (isSpanOrReadOnlySpan) { EmitCharCompareAndBranch(key, syntaxNode, stringConstant, targetLabel, (IReference)(object)sequenceEqualsMethodRef, (IReference)(object)asSpanMethodRef); } else { EmitStringCompareAndBranch(key, syntaxNode, stringConstant, targetLabel, (IReference)(object)stringEqualityMethodRef); } }; ILBuilder builder = _builder; LocalOrParameter val3 = key; LocalDefinition obj = val; object obj2 = _003C_003EO._003C1_003E__ComputeStringHash; if (obj2 == null) { GetStringHashCode val4 = SynthesizedStringSwitchHashMethod.ComputeStringHash; _003C_003EO._003C1_003E__ComputeStringHash = val4; obj2 = (object)val4; } builder.EmitStringSwitchJumpTable(switchCaseLabels, (object)fallThroughLabel, val3, obj, val2, (GetStringHashCode)obj2); if (val != null) { FreeTemp(val); } } private IMethodReference? GetLengthMethodRef(SyntaxNode syntaxNode, TypeSymbol keyType, bool isReadOnlySpan, bool isSpanOrReadOnlySpan) { if (isSpanOrReadOnlySpan) { MethodSymbol methodSymbol = ((MethodSymbol)Binder.GetWellKnownTypeMember(((PEModuleBuilder)_module).Compilation, (WellKnownMember)(isReadOnlySpan ? 407 : 401), _diagnostics, null, syntaxNode)).AsMember((NamedTypeSymbol)keyType); return _module.Translate(methodSymbol, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); } MethodSymbol methodSymbol2 = ((PEModuleBuilder)_module).Compilation.GetSpecialTypeMember((SpecialMember)11) as MethodSymbol; if (methodSymbol2 != null && !methodSymbol2.HasUseSiteError) { return _module.Translate(methodSymbol2, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); } return null; } private IMethodReference? GetIndexerRef(SyntaxNode syntaxNode, TypeSymbol keyType, bool isReadOnlySpan, bool isSpanOrReadOnlySpan) { if (isSpanOrReadOnlySpan) { MethodSymbol methodSymbol = (MethodSymbol)Binder.GetWellKnownTypeMember(((PEModuleBuilder)_module).Compilation, (WellKnownMember)(isReadOnlySpan ? 406 : 400), _diagnostics, null, syntaxNode); if (methodSymbol != null && !methodSymbol.HasUseSiteError) { MethodSymbol methodSymbol2 = methodSymbol.AsMember((NamedTypeSymbol)keyType); return _module.Translate(methodSymbol2, null, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); } } else { MethodSymbol methodSymbol3 = ((PEModuleBuilder)_module).Compilation.GetSpecialTypeMember((SpecialMember)12) as MethodSymbol; if (methodSymbol3 != null && !methodSymbol3.HasUseSiteError) { return _module.Translate(methodSymbol3, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); } } return null; } private void EmitStringCompareAndBranch(LocalOrParameter key, SyntaxNode syntaxNode, ConstantValue stringConstant, object targetLabel, IReference stringEqualityMethodRef) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) _builder.EmitLoad(key); _builder.EmitConstantValue(stringConstant); _builder.EmitOpCode(ILOpCode.Call, -1); _builder.EmitToken(stringEqualityMethodRef, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag, (RawTokenEncoding)0); _builder.EmitBranch(ILOpCode.Brtrue, targetLabel, ILOpCode.Brfalse); } private void EmitCharCompareAndBranch(LocalOrParameter key, SyntaxNode syntaxNode, ConstantValue stringConstant, object targetLabel, IReference sequenceEqualsRef, IReference asSpanRef) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) _builder.EmitLoad(key); _builder.EmitConstantValue(stringConstant); _builder.EmitOpCode(ILOpCode.Call, 0); _builder.EmitToken(asSpanRef, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag, (RawTokenEncoding)0); _builder.EmitOpCode(ILOpCode.Call, -1); _builder.EmitToken(sequenceEqualsRef, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag, (RawTokenEncoding)0); _builder.EmitBranch(ILOpCode.Brtrue, targetLabel, ILOpCode.Brfalse); } private LocalDefinition GetLocal(BoundLocal localExpression) { LocalSymbol localSymbol = localExpression.LocalSymbol; return GetLocal(localSymbol); } private LocalDefinition GetLocal(LocalSymbol symbol) { return _builder.LocalSlotManager.GetLocal((ILocalSymbolInternal)(object)symbol); } private LocalDefinition DefineLocal(LocalSymbol local, SyntaxNode syntaxNode) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Invalid comparison between Unknown and I4 //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Invalid comparison between Unknown and I4 ImmutableArray immutableArray = ((!local.IsCompilerGenerated && local.Type.ContainsDynamic()) ? CSharpCompilation.DynamicTransformsEncoder.Encode(local.Type, (RefKind)0, 0) : ImmutableArray.Empty); ImmutableArray immutableArray2 = ((!local.IsCompilerGenerated && local.Type.ContainsTupleNames()) ? CSharpCompilation.TupleNamesEncoder.Encode(local.Type) : ImmutableArray.Empty); if (local.IsConst) { MetadataConstant val = ((PEModuleBuilder)_module).CreateConstant(local.Type, local.ConstantValue, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); LocalConstantDefinition val2 = new LocalConstantDefinition(local.Name, local.GetFirstLocationOrNone(), val, immutableArray, immutableArray2); _builder.AddLocalConstantToScope(val2); return null; } if (IsStackLocal(local)) { return null; } LocalSlotConstraints val3; ITypeReference val4; if (local.DeclarationKind == LocalDeclarationKind.FixedVariable && local.IsPinned) { val3 = (LocalSlotConstraints)3; TypeSymbol pointedAtType = ((PointerTypeSymbol)local.Type).PointedAtType; ITypeReference obj; if (!pointedAtType.IsVoidType()) { obj = ((PEModuleBuilder)_module).Translate(pointedAtType, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); } else { ITypeReference specialType = (ITypeReference)(object)((PEModuleBuilder)_module).GetSpecialType((SpecialType)21, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); obj = specialType; } val4 = obj; } else { val3 = (LocalSlotConstraints)((local.IsPinned ? 2 : 0) | (((int)local.RefKind != 0) ? 1 : 0)); val4 = ((PEModuleBuilder)_module).Translate(local.Type, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); } ((CommonPEModuleBuilder)_module).GetFakeSymbolTokenForIL((IReference)(object)val4, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag); LocalDebugId localId; string localDebugName = GetLocalDebugName((ILocalSymbolInternal)(object)local, out localId); LocalDefinition val5 = _builder.LocalSlotManager.DeclareLocal(val4, (ILocalSymbolInternal)(object)local, localDebugName, local.SynthesizedKind, localId, SynthesizedLocalKindExtensions.PdbAttributes(local.SynthesizedKind), val3, immutableArray, immutableArray2, SynthesizedLocalKindExtensions.IsSlotReusable(local.SynthesizedKind, (int)_ilEmitStyle != 2)); bool flag = val5.Name != null; if (flag) { bool flag2 = (int)local.SynthesizedKind == 0; if (flag2) { bool flag3; switch (local.ScopeDesignatorOpt?.Kind()) { case SyntaxKind.SwitchSection: case SyntaxKind.SwitchExpressionArm: flag3 = true; break; default: flag3 = false; break; } flag2 = flag3; } flag = !flag2; } if (flag) { _builder.AddLocalToScope(val5); } return val5; } private string GetLocalDebugName(ILocalSymbolInternal local, out LocalDebugId localId) { //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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 //IL_0031: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) localId = LocalDebugId.None; if (local.IsImportedFromMetadata) { return ((ISymbolInternal)local).Name; } SynthesizedLocalKind synthesizedKind = local.SynthesizedKind; if (!SynthesizedLocalKindExtensions.IsLongLived(synthesizedKind) || (int)synthesizedKind == 34) { return null; } if ((int)_ilEmitStyle == 0) { SyntaxNode declaratorSyntax = local.GetDeclaratorSyntax(); int num = _method.CalculateLocalSyntaxOffset(LambdaUtilities.GetDeclaratorPosition(declaratorSyntax), declaratorSyntax.SyntaxTree); int num2 = _synthesizedLocalOrdinals.AssignLocalOrdinal(synthesizedKind, num); localId = new LocalDebugId(num, num2); } return ((ISymbolInternal)local).Name ?? GeneratedNames.MakeSynthesizedLocalName(synthesizedKind, ref _uniqueNameId); } private bool IsSlotReusable(LocalSymbol local) { //IL_0001: 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_000d: Invalid comparison between Unknown and I4 return SynthesizedLocalKindExtensions.IsSlotReusable(local.SynthesizedKind, (int)_ilEmitStyle != 2); } private void FreeLocal(LocalSymbol local) { if (local.Name == null && IsSlotReusable(local) && !IsStackLocal(local)) { _builder.LocalSlotManager.FreeLocal((ILocalSymbolInternal)(object)local); } } private LocalDefinition AllocateTemp(TypeSymbol type, SyntaxNode syntaxNode, LocalSlotConstraints slotConstraints = (LocalSlotConstraints)0) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) return _builder.LocalSlotManager.AllocateSlot(((PEModuleBuilder)_module).Translate(type, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag), slotConstraints, default(ImmutableArray), default(ImmutableArray)); } private void FreeTemp(LocalDefinition temp) { _builder.LocalSlotManager.FreeSlot(temp); } private void FreeOptTemp(LocalDefinition temp) { if (temp != null) { FreeTemp(temp); } } }