Files

6902 lines
231 KiB
C#
Raw Permalink Normal View History

2026-08-27 10:56:38 -06:00
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<BoundExpression> initializers)
{
public readonly int Index = index;
public readonly ImmutableArray<BoundExpression> 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<LabelSymbol, GeneratedLabelSymbol> _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<LabelSymbol, GeneratedLabelSymbol> dictionary = _labelClones;
if (dictionary == null)
{
dictionary = (_labelClones = new Dictionary<LabelSymbol, GeneratedLabelSymbol>());
}
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<BoundExpression, bool> _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<LocalSymbol> _stackLocals;
private ArrayBuilder<LocalDefinition> _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<int> _asyncYieldPoints;
private ArrayBuilder<int> _asyncResumePoints;
private IndirectReturnState _indirectReturnState;
private PooledDictionary<object, TextSpan> _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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<bool>.Empty, ImmutableArray<string>.Empty, false);
}
else
{
val = AllocateTemp(_method.ReturnType, _boundBody.Syntax, val2);
}
_returnTemp = val;
}
return val;
}
}
private bool EnableEnumArrayBlockInitialization => ((PEModuleBuilder<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_module).Compilation.Options).DebugPlusMode;
}
private bool IsPeVerifyCompatEnabled()
{
return ((PEModuleBuilder<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_module).Compilation.IsPeVerifyCompatEnabled;
}
internal static bool IsStackLocal(LocalSymbol local, HashSet<LocalSymbol> 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<int> asyncYieldPoints, out ImmutableArray<int> asyncResumePoints, out bool hasStackAlloc)
{
GenerateImpl();
hasStackAlloc = _sawStackalloc;
asyncCatchHandlerOffset = (((BindingDiagnosticBag)_diagnostics).HasAnyErrors() ? (-1) : _builder.GetILOffsetFromMarker(_asyncCatchHandlerOffset));
ArrayBuilder<int> asyncYieldPoints2 = _asyncYieldPoints;
ArrayBuilder<int> asyncResumePoints2 = _asyncResumePoints;
if (asyncYieldPoints2 == null || ((BindingDiagnosticBag)_diagnostics).HasAnyErrors())
{
asyncYieldPoints = ImmutableArray<int>.Empty;
asyncResumePoints = ImmutableArray<int>.Empty;
return;
}
ArrayBuilder<int> instance = ArrayBuilder<int>.GetInstance();
ArrayBuilder<int> instance2 = ArrayBuilder<int>.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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<RawSequencePoint> 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<object, TextSpan>.GetInstance();
}
((Dictionary<object, TextSpan>)(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, TextSpan>)(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<LocalDefinition> val = _expressionTemps;
if (val == null)
{
val = (_expressionTemps = ArrayBuilder<LocalDefinition>.GetInstance());
}
val.Add(temp);
}
}
private void ReleaseExpressionTemps()
{
ArrayBuilder<LocalDefinition> 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<BoundExpression> 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<BoundExpression> initializers = inits.Initializers;
ArrayInitializerStyle arrayInitializerStyle = ShouldEmitBlockInitializer(arrayType.ElementType, initializers);
if (arrayInitializerStyle == ArrayInitializerStyle.Element)
{
EmitElementInitializers(arrayType, initializers, includeConstants: true);
return;
}
ImmutableArray<byte> 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<BoundExpression> inits, bool includeConstants)
{
if (!IsMultidimensionalInitializer(inits))
{
EmitVectorElementInitializers(arrayType, inits, includeConstants);
}
else
{
EmitMultidimensionalElementInitializers(arrayType, inits, includeConstants);
}
}
private void EmitVectorElementInitializers(ArrayTypeSymbol arrayType, ImmutableArray<BoundExpression> 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<BoundExpression> inits, bool includeConstants)
{
ArrayBuilder<IndexDesc> val = new ArrayBuilder<IndexDesc>();
for (int i = 0; i < inits.Length; i++)
{
ArrayBuilderExtensions.Push<IndexDesc>(val, new IndexDesc(i, ((BoundArrayInitialization)inits[i]).Initializers));
EmitAllElementInitializersRecursive(arrayType, val, includeConstants);
}
}
private void EmitAllElementInitializersRecursive(ArrayTypeSymbol arrayType, ArrayBuilder<IndexDesc> 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<BoundExpression> initializers = ArrayBuilderExtensions.Peek<IndexDesc>(indices).Initializers;
if (IsMultidimensionalInitializer(initializers))
{
for (int i = 0; i < initializers.Length; i++)
{
ArrayBuilderExtensions.Push<IndexDesc>(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<IndexDesc> 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<IndexDesc>(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<BoundExpression> 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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<BoundExpression> inits, ref int initCount, ref int constInits)
{
if (inits.Length == 0)
{
return;
}
ImmutableArray<BoundExpression>.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<byte> GetRawData(ImmutableArray<BoundExpression> initializers)
{
BlobBuilder blobBuilder = new BlobBuilder(initializers.Length * 4);
SerializeArrayRecursive(blobBuilder, initializers);
return blobBuilder.ToImmutableArray();
}
private void SerializeArrayRecursive(BlobBuilder bw, ImmutableArray<BoundExpression> inits)
{
if (inits.Length == 0)
{
return;
}
if (inits[0].Kind == BoundKind.ArrayInitialization)
{
ImmutableArray<BoundExpression>.Enumerator enumerator = inits.GetEnumerator();
while (enumerator.MoveNext())
{
BoundExpression current = enumerator.Current;
SerializeArrayRecursive(bw, ((BoundArrayInitialization)current).Initializers);
}
}
else
{
ImmutableArray<BoundExpression>.Enumerator enumerator = inits.GetEnumerator();
while (enumerator.MoveNext())
{
AsConstOrDefault(enumerator.Current).Serialize(bw);
}
}
}
private static bool IsMultidimensionalInitializer(ImmutableArray<BoundExpression> 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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_module).Compilation, (WellKnownMember)403, _diagnostics, null, wrappedExpression.Syntax, isOptional: true);
if ((object)methodSymbol == null)
{
return false;
}
ImmutableArray<byte> data = default(ImmutableArray<byte>);
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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<byte> data)
{
data = default(ImmutableArray<byte>);
if (initializer == null)
{
return -1;
}
ImmutableArray<BoundExpression> initializers = initializer.Initializers;
if (initializers.Any((BoundExpression init) => init.ConstantValueOpt == (ConstantValue)null))
{
return -1;
}
int length = initializers.Length;
if (length == 0)
{
data = ImmutableArray<byte>.Empty;
return 0;
}
BlobBuilder blobBuilder = new BlobBuilder(initializers.Length * 4);
ImmutableArray<BoundExpression>.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<Symbol>.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<LocalSymbol>.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<LocalSymbol>.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<LocalSymbol>.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<BoundExpression> sideEffects = sequence.SideEffects;
if (!sideEffects.IsDefaultOrEmpty)
{
ImmutableArray<BoundExpression>.Enumerator enumerator = sideEffects.GetEnumerator();
while (enumerator.MoveNext())
{
BoundExpression current = enumerator.Current;
EmitExpression(current, used: false);
}
}
}
private void EmitArguments(ImmutableArray<BoundExpression> arguments, ImmutableArray<ParameterSymbol> parameters, ImmutableArray<RefKind> 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<BoundExpression> arguments, ImmutableArray<ParameterSymbol> parameters, ImmutableArray<RefKind> 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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<BoundExpression> 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<BoundCall> instance = ArrayBuilder<BoundCall>.GetInstance();
ArrayBuilderExtensions.Push<BoundCall>(instance, call);
call = nested;
while (receiverIsInstanceCall(call, out nested))
{
ArrayBuilderExtensions.Push<BoundCall>(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<BoundCall>(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<BoundExpression> 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<BoundExpression> 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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_module).Compilation.GetSpecialTypeMember((SpecialMember)114) || (object)originalDefinition == ((PEModuleBuilder<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_module).Compilation.GetSpecialTypeMember((SpecialMember)115) || (object)originalDefinition == ((PEModuleBuilder<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<BoundExpression> 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<BoundExpression>.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<BoundExpression>.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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_module).Compilation.GetWellKnownTypeMember((WellKnownMember)404)) || (length == 3 && (object)expression.Constructor.OriginalDefinition == ((PEModuleBuilder<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_module).GetModuleVersionId(((PEModuleBuilder<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_module).GetInstrumentationPayloadRoot(node.AnalysisKind, ((PEModuleBuilder<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<BoundBinaryOperator> instance = ArrayBuilder<BoundBinaryOperator>.GetInstance();
ArrayBuilderExtensions.Push<BoundBinaryOperator>(instance, expression);
do
{
ArrayBuilderExtensions.Push<BoundBinaryOperator>(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<BoundBinaryOperator>(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<BoundExpression> initializers = inits.Initializers;
ArrayInitializerStyle arrayInitializerStyle = ShouldEmitBlockInitializerForStackAlloc(type2, initializers);
if (arrayInitializerStyle == ArrayInitializerStyle.Element)
{
EmitElementStackAllocInitializers(type2, initializers, includeConstants: true);
return;
}
ImmutableArray<byte> 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<BoundExpression> 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<BoundExpression> inits, ref int initCount, ref int constInits)
{
if (inits.Length == 0)
{
return;
}
ImmutableArray<BoundExpression>.Enumerator enumerator = inits.GetEnumerator();
while (enumerator.MoveNext())
{
BoundExpression current = enumerator.Current;
initCount++;
if (current.ConstantValueOpt != (ConstantValue)null)
{
constInits++;
}
}
}
private void EmitElementStackAllocInitializers(TypeSymbol elementType, ImmutableArray<BoundExpression> 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<BoundExpression>.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<int>.GetInstance();
_asyncResumePoints = ArrayBuilder<int>.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<object>, bool)> instance = ArrayBuilder<(BoundExpression, StrongBox<object>, bool)>.GetInstance();
StrongBox<object> strongBox = new StrongBox<object>(dest);
ArrayBuilderExtensions.Push<(BoundExpression, StrongBox<object>, bool)>(instance, ((BoundExpression)boundBinaryOperator, strongBox, sense));
(BoundExpression, StrongBox<object>, bool) tuple;
while (true)
{
tuple = ArrayBuilderExtensions.Pop<(BoundExpression, StrongBox<object>, 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<object> item = new StrongBox<object>();
ArrayBuilderExtensions.Push<(BoundExpression, StrongBox<object>, bool)>(instance, ((BoundExpression)null, item, true));
ArrayBuilderExtensions.Push<(BoundExpression, StrongBox<object>, bool)>(instance, (boundBinaryOperator2.Right, tuple.Item2, tuple.Item3));
ArrayBuilderExtensions.Push<(BoundExpression, StrongBox<object>, bool)>(instance, (boundBinaryOperator2.Left, item, !tuple.Item3));
}
else
{
ArrayBuilderExtensions.Push<(BoundExpression, StrongBox<object>, bool)>(instance, (boundBinaryOperator2.Right, tuple.Item2, tuple.Item3));
ArrayBuilderExtensions.Push<(BoundExpression, StrongBox<object>, 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<LocalSymbol>.Enumerator enumerator = block.Locals.GetEnumerator();
while (enumerator.MoveNext())
{
LocalSymbol current = enumerator.Current;
ImmutableArray<SyntaxReference> 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<LocalSymbol>.Enumerator enumerator = block.Locals.GetEnumerator();
while (enumerator.MoveNext())
{
LocalSymbol current2 = enumerator.Current;
FreeLocal(current2);
}
_builder.CloseLocalScope();
}
}
private void EmitStatements(ImmutableArray<BoundStatement> statements)
{
ImmutableArray<BoundStatement>.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<LocalSymbol>.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<StateMachineFieldSymbol>.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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<BoundCatchBlock>.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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_module).GetSpecialType((SpecialType)1, catchBlock.Syntax, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag);
obj2 = specialType;
}
else
{
obj2 = ((PEModuleBuilder<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<LocalSymbol>.Enumerator enumerator = catchBlock.Locals.GetEnumerator();
while (enumerator.MoveNext())
{
LocalSymbol current = enumerator.Current;
ImmutableArray<SyntaxReference> 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, object>>(((ConstantValue value, LabelSymbol label) p) => new KeyValuePair<ConstantValue, object>(p.value, p.label)).ToArray(), dispatch.DefaultLabel, dispatch.LengthBasedStringSwitchDataOpt);
}
private void EmitSwitchHeader(BoundExpression expression, KeyValuePair<ConstantValue, object>[] 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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_module).Compilation, (SpecialType)8, val, _diagnostics);
LocalDefinition val2 = AllocateTemp(specialType, val, (LocalSlotConstraints)0);
ImmutableArray<LengthBasedStringSwitchData.CharJumpTable>.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<ConstantValue, object>>(((char value, LabelSymbol label) p) => new KeyValuePair<ConstantValue, object>(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<LengthBasedStringSwitchData.StringJumpTable>.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<ConstantValue, object>>(((string value, LabelSymbol label) p) => new KeyValuePair<ConstantValue, object>(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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<ConstantValue, object>>(((int value, LabelSymbol label) p) => new KeyValuePair<ConstantValue, object>(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<ConstantValue, object>[] 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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_module).Compilation, (WellKnownMember)(flag2 ? 474 : 473), _diagnostics, null, syntaxNode)).Construct(Binder.GetSpecialType(((PEModuleBuilder<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_module).Compilation, (SpecialType)8, syntaxNode, _diagnostics));
sequenceEqualsMethodRef = _module.Translate(methodSymbol, null, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag);
MethodSymbol methodSymbol2 = (MethodSymbol)Binder.GetWellKnownTypeMember(((PEModuleBuilder<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_module).Compilation, (WellKnownMember)475, _diagnostics, null, syntaxNode);
asSpanMethodRef = _module.Translate(methodSymbol2, null, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag);
}
else
{
MethodSymbol methodSymbol3 = ((PEModuleBuilder<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_module).Compilation, (WellKnownMember)(isReadOnlySpan ? 407 : 401), _diagnostics, null, syntaxNode)).AsMember((NamedTypeSymbol)keyType);
return _module.Translate(methodSymbol, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag);
}
MethodSymbol methodSymbol2 = ((PEModuleBuilder<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<bool> immutableArray = ((!local.IsCompilerGenerated && local.Type.ContainsDynamic()) ? CSharpCompilation.DynamicTransformsEncoder.Encode(local.Type, (RefKind)0, 0) : ImmutableArray<bool>.Empty);
ImmutableArray<string> immutableArray2 = ((!local.IsCompilerGenerated && local.Type.ContainsTupleNames()) ? CSharpCompilation.TupleNamesEncoder.Encode(local.Type) : ImmutableArray<string>.Empty);
if (local.IsConst)
{
MetadataConstant val = ((PEModuleBuilder<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_module).Translate(pointedAtType, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag);
}
else
{
ITypeReference specialType = (ITypeReference)(object)((PEModuleBuilder<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_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<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)_module).Translate(type, syntaxNode, ((BindingDiagnosticBag)_diagnostics).DiagnosticBag), slotConstraints, default(ImmutableArray<bool>), default(ImmutableArray<string>));
}
private void FreeTemp(LocalDefinition temp)
{
_builder.LocalSlotManager.FreeSlot(temp);
}
private void FreeOptTemp(LocalDefinition temp)
{
if (temp != null)
{
FreeTemp(temp);
}
}
}