Beispiel #1
0
            Instruction GetLocalsValue(int index, MethodBody body)
            {
                var instr = locals?[index];

                if (instr != null)
                {
                    return(instr);
                }

                if (!body.InitLocals)
                {
                    return(null);
                }

                // local variables don't need to be explicitly initialized
                return(CodeRewriterStep.CreateConstantResultInstruction(body.Variables[index].VariableType));
            }
Beispiel #2
0
        void FindConstantExpressionsMethods(Collection <TypeDefinition> types)
        {
            foreach (var type in types)
            {
                if (type.IsInterface)
                {
                    continue;
                }

                if (!type.HasMethods)
                {
                    continue;
                }

                foreach (var method in type.Methods)
                {
                    if (!method.HasBody)
                    {
                        continue;
                    }

                    if (method.ReturnType.MetadataType == MetadataType.Void)
                    {
                        continue;
                    }

                    switch (Annotations.GetAction(method))
                    {
                    case MethodAction.ConvertToThrow:
                        continue;

                    case MethodAction.ConvertToStub:
                        var instruction = CodeRewriterStep.CreateConstantResultInstruction(Context, method);
                        if (instruction != null)
                        {
                            constExprMethods[method] = instruction;
                        }

                        continue;
                    }

                    if (method.IsIntrinsic())
                    {
                        continue;
                    }

                    if (constExprMethods.ContainsKey(method))
                    {
                        continue;
                    }

                    if (!Context.IsOptimizationEnabled(CodeOptimizations.IPConstantPropagation, method))
                    {
                        continue;
                    }

                    var analyzer = new ConstantExpressionMethodAnalyzer(method);
                    if (analyzer.Analyze())
                    {
                        constExprMethods[method] = analyzer.Result;
                    }
                }

                if (type.HasNestedTypes)
                {
                    FindConstantExpressionsMethods(type.NestedTypes);
                }
            }
        }
Beispiel #3
0
        bool TryInlineBodyDependencies(ref BodyReducer reducer)
        {
            bool        changed      = false;
            var         instructions = reducer.Body.Instructions;
            Instruction targetResult;

            for (int i = 0; i < instructions.Count; ++i)
            {
                var instr = instructions[i];
                switch (instr.OpCode.Code)
                {
                case Code.Call:
                    var target = (MethodReference)instr.Operand;
                    var md     = target.Resolve();
                    if (md == null)
                    {
                        break;
                    }

                    if (!md.IsStatic)
                    {
                        break;
                    }

                    if (!constExprMethods.TryGetValue(md, out targetResult))
                    {
                        break;
                    }

                    if (md.HasParameters)
                    {
                        break;
                    }

                    reducer.Rewrite(i, targetResult);
                    changed = true;
                    break;

                case Code.Ldsfld:
                    var ftarget = (FieldReference)instr.Operand;
                    var field   = ftarget.Resolve();
                    if (field == null)
                    {
                        break;
                    }

                    if (Context.Annotations.TryGetFieldUserValue(field, out object value))
                    {
                        targetResult = CodeRewriterStep.CreateConstantResultInstruction(field.FieldType, value);
                        if (targetResult == null)
                        {
                            break;
                        }
                        reducer.Rewrite(i, targetResult);
                        changed = true;
                    }
                    break;

                case Code.Sizeof:
                    //
                    // sizeof (IntPtr) and sizeof (UIntPtr) are just aliases for IntPtr.Size and UIntPtr.Size
                    // which are simple static properties commonly overwritten. Instead of forcing C# code style
                    // we handle both via static Size property
                    //
                    MethodDefinition sizeOfImpl = null;

                    var operand = (TypeReference)instr.Operand;
                    if (operand.MetadataType == MetadataType.UIntPtr)
                    {
                        sizeOfImpl = UIntPtrSize ?? (UIntPtrSize = FindSizeMethod(operand.Resolve()));
                    }

                    if (operand.MetadataType == MetadataType.IntPtr)
                    {
                        sizeOfImpl = IntPtrSize ?? (IntPtrSize = FindSizeMethod(operand.Resolve()));
                    }

                    if (sizeOfImpl != null && constExprMethods.TryGetValue(sizeOfImpl, out targetResult))
                    {
                        reducer.Rewrite(i, targetResult);
                        changed = true;
                    }

                    break;
                }
            }

            return(changed);
        }