protected internal override void VisitNewObj(NewObj inst) { if (TransformDecimalCtorToConstant(inst, out LdcDecimal decimalConstant)) { context.Step("TransformDecimalCtorToConstant", inst); inst.ReplaceWith(decimalConstant); return; } Block block; if (TransformSpanTCtorContainingStackAlloc(inst, out ILInstruction locallocSpan)) { inst.ReplaceWith(locallocSpan); block = null; ILInstruction stmt = locallocSpan; while (stmt.Parent != null) { if (stmt.Parent is Block b) { block = b; break; } stmt = stmt.Parent; } //ILInlining.InlineIfPossible(block, stmt.ChildIndex - 1, context); return; } if (TransformArrayInitializers.TransformSpanTArrayInitialization(inst, context, out block)) { context.Step("TransformSpanTArrayInitialization: single-dim", inst); inst.ReplaceWith(block); return; } base.VisitNewObj(inst); }
protected internal override void VisitNewObj(NewObj inst) { if (TransformDecimalCtorToConstant(inst, out LdcDecimal decimalConstant)) { context.Step("TransformDecimalCtorToConstant", inst); inst.ReplaceWith(decimalConstant); return; } Block block; if (TransformSpanTCtorContainingStackAlloc(inst, out ILInstruction locallocSpan)) { context.Step("new Span<T>(stackalloc) -> stackalloc Span<T>", inst); inst.ReplaceWith(locallocSpan); block = null; ILInstruction stmt = locallocSpan; while (stmt.Parent != null) { if (stmt.Parent is Block b) { block = b; break; } stmt = stmt.Parent; } // Special case to eliminate extra store if (stmt.GetNextSibling() is StLoc storeStmt && storeStmt.Value is LdLoc) { ILInlining.InlineIfPossible(block, stmt.ChildIndex, context); } return; } if (TransformArrayInitializers.TransformSpanTArrayInitialization(inst, context, out block)) { context.Step("TransformSpanTArrayInitialization: single-dim", inst); inst.ReplaceWith(block); return; } if (TransformDelegateCtorLdVirtFtnToLdVirtDelegate(inst, out LdVirtDelegate ldVirtDelegate)) { context.Step("new Delegate(target, ldvirtftn Method) -> ldvirtdelegate Delegate Method(target)", inst); inst.ReplaceWith(ldVirtDelegate); return; } base.VisitNewObj(inst); }
protected internal override void VisitNewObj(NewObj inst) { LdcDecimal decimalConstant; if (TransformDecimalCtorToConstant(inst, out decimalConstant)) { context.Step("TransformDecimalCtorToConstant", inst); inst.ReplaceWith(decimalConstant); return; } base.VisitNewObj(inst); }
ILFunction TransformDelegateConstruction(NewObj value, out ILInstruction target) { target = null; if (!IsDelegateConstruction(value)) { return(null); } var targetMethod = ((IInstructionWithMethodOperand)value.Arguments[1]).Method; if (!IsAnonymousMethod(decompilationContext.CurrentTypeDefinition, targetMethod)) { return(null); } if (LocalFunctionDecompiler.IsLocalFunctionMethod(targetMethod.ParentModule.PEFile, (MethodDefinitionHandle)targetMethod.MetadataToken)) { return(null); } target = value.Arguments[0]; if (targetMethod.MetadataToken.IsNil) { return(null); } var methodDefinition = context.PEFile.Metadata.GetMethodDefinition((MethodDefinitionHandle)targetMethod.MetadataToken); if (!methodDefinition.HasBody()) { return(null); } var genericContext = GenericContextFromTypeArguments(targetMethod.Substitution); if (genericContext == null) { return(null); } var ilReader = context.CreateILReader(); var body = context.PEFile.Reader.GetMethodBody(methodDefinition.RelativeVirtualAddress); var function = ilReader.ReadIL((MethodDefinitionHandle)targetMethod.MetadataToken, body, genericContext.Value, context.CancellationToken); function.DelegateType = value.Method.DeclaringType; function.CheckInvariant(ILPhase.Normal); // Embed the lambda into the parent function's ILAst, so that "Show steps" can show // how the lambda body is being transformed. value.ReplaceWith(function); var contextPrefix = targetMethod.Name; foreach (ILVariable v in function.Variables.Where(v => v.Kind != VariableKind.Parameter)) { v.Name = contextPrefix + v.Name; } var nestedContext = new ILTransformContext(context, function); function.RunTransforms(CSharpDecompiler.GetILTransforms().TakeWhile(t => !(t is DelegateConstruction)).Concat(GetTransforms()), nestedContext); nestedContext.Step("DelegateConstruction (ReplaceDelegateTargetVisitor)", function); function.AcceptVisitor(new ReplaceDelegateTargetVisitor(target, function.Variables.SingleOrDefault(v => v.Index == -1 && v.Kind == VariableKind.Parameter))); // handle nested lambdas nestedContext.StepStartGroup("DelegateConstruction (nested lambdas)", function); ((IILTransform) new DelegateConstruction()).Run(function, nestedContext); nestedContext.StepEndGroup(); function.AddILRange(target); function.AddILRange(value); function.AddILRange(value.Arguments[1]); return(function); }