Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }