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)); }
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); } } }
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); }