private static void FindPattern(List <IStatement> statements) { int n = statements.Count; for (int i = n - 1; 0 <= i; i--) { IEmptyStatement emptyStatement = statements[i] as IEmptyStatement; if (emptyStatement == null) { continue; } if (IteratorHelper.EnumerableIsNotEmpty(emptyStatement.Locations)) { continue; } statements.RemoveAt(i); } return; }
/// <summary> /// /// </summary> /// <param name="unitNamespaceReference"></param> /// <param name="internFactory"></param> public virtual void Copy(IUnitNamespaceReference unitNamespaceReference, IInternFactory internFactory) { if (IteratorHelper.EnumerableIsNotEmpty(unitNamespaceReference.Attributes)) { this.attributes = new List <ICustomAttribute>(unitNamespaceReference.Attributes); } else { this.attributes = null; } if (IteratorHelper.EnumerableIsNotEmpty(unitNamespaceReference.Locations)) { this.locations = new List <ILocation>(unitNamespaceReference.Locations); } else { this.locations = null; } }
public override void TraverseChildren(IEventDefinition eventDefinition) { PrintAttributes(eventDefinition); PrintToken(CSharpToken.Indent); IMethodDefinition eventMeth = eventDefinition.Adder == null ? eventDefinition.Remover.ResolvedMethod : eventDefinition.Adder.ResolvedMethod; if (!eventDefinition.ContainingTypeDefinition.IsInterface && IteratorHelper.EnumerableIsEmpty(MemberHelper.GetExplicitlyOverriddenMethods(eventMeth))) { PrintEventDefinitionVisibility(eventDefinition); } PrintMethodDefinitionModifiers(eventMeth); PrintToken(CSharpToken.Event); PrintEventDefinitionDelegateType(eventDefinition); PrintToken(CSharpToken.Space); PrintEventDefinitionName(eventDefinition); PrintToken(CSharpToken.Semicolon); }
/// <summary> /// /// </summary> /// <param name="customAttribute"></param> /// <param name="internFactory"></param> public void Copy(ICustomAttribute customAttribute, IInternFactory internFactory) { if (IteratorHelper.EnumerableIsNotEmpty(customAttribute.Arguments)) { this.arguments = new List <IMetadataExpression>(customAttribute.Arguments); } else { this.arguments = null; } this.constructor = customAttribute.Constructor; if (customAttribute.NumberOfNamedArguments > 0) { this.namedArguments = new List <IMetadataNamedArgument>(customAttribute.NamedArguments); } else { this.namedArguments = null; } }
internal static bool HasFieldOfUnspecifiedType(ITypeReference type, IEnumerable <ITypeDefinitionMember> members, LanguageSpecificCompilationHelper helper) { bool errorFound = false; foreach (var member in members) { var field = member as IFieldDefinition; if (field != null && field.Type == helper.Compilation.PlatformType.SystemVoid.ResolvedType) { var fieldDecl = ((Cci.Ast.FieldDefinition)field).Declaration as FieldDefinition; var location = IteratorHelper.First(helper.Compilation.SourceLocationProvider.GetPrimarySourceLocationsFor(type.Locations)); helper.ReportError( new VccErrorMessage(location, Error.IllegalUseOfUndefinedType, field.Name.Value, fieldDecl != null ? fieldDecl.Type.SourceLocation.Source : helper.GetTypeName(field.Type.ResolvedType))); errorFound = true; } } return(errorFound); }
private void CreateExceptionBlocks(DecompiledBlock block) { Contract.Requires(block != null); if (IteratorHelper.EnumerableIsEmpty(this.ilMethodBody.OperationExceptionInformation)) { return; } List <IOperationExceptionInformation> handlers = new List <IOperationExceptionInformation>(this.ilMethodBody.OperationExceptionInformation); handlers.Sort(CompareHandlers); foreach (var exInfo in handlers) { Contract.Assume(exInfo != null); this.CreateNestedBlock(block, exInfo.TryStartOffset, exInfo.TryEndOffset); if (exInfo.HandlerKind == HandlerKind.Filter) { this.CreateNestedBlock(block, exInfo.FilterDecisionStartOffset, exInfo.HandlerEndOffset); } this.CreateNestedBlock(block, exInfo.HandlerStartOffset, exInfo.HandlerEndOffset); } }
/// <summary> /// /// </summary> /// <param name="unitNamespace"></param> /// <param name="internFactory"></param> public virtual void Copy(IUnitNamespace unitNamespace, IInternFactory internFactory) { if (IteratorHelper.EnumerableIsNotEmpty(unitNamespace.Attributes)) { this.attributes = new List <ICustomAttribute>(unitNamespace.Attributes); } else { this.attributes = null; } if (IteratorHelper.EnumerableIsNotEmpty(unitNamespace.Locations)) { this.locations = new List <ILocation>(unitNamespace.Locations); } else { this.locations = null; } this.members = new List <INamespaceMember>(unitNamespace.Members); this.name = unitNamespace.Name; this.unit = unitNamespace.Unit; }
public void ReportDuplicateIncompatibleTypedefs() { Dictionary <int, TypedefDeclaration> seenTypedefs = new Dictionary <int, TypedefDeclaration>(); foreach (var typedef in IteratorHelper.GetFilterEnumerable <ITypeDeclarationMember, TypedefDeclaration>(this.CompilationPart.GlobalDeclarationContainer.TypeDeclarationMembers)) { TypedefDeclaration seenTypedef; if (seenTypedefs.TryGetValue(typedef.Name.UniqueKey, out seenTypedef)) { if (!TypeHelper.TypesAreEquivalent(typedef.Type.ResolvedType, seenTypedef.Type.ResolvedType)) { this.Helper.ReportError( new VccErrorMessage(typedef.SourceLocation, Error.DuplicateTypedef, typedef.Name.Value, this.Helper.GetTypeName(seenTypedef.Type.ResolvedType), this.Helper.GetTypeName(typedef.Type.ResolvedType))); } } else { seenTypedefs.Add(typedef.Name.UniqueKey, typedef); } } }
public bool MoveNext() { while (true) { --iterationIndex; if (iterationIndex < 0) { iterationIndex = 16 * 16 * 16 - 1; iterationChunkLocation.z -= 16; if (iterationChunkLocation.z < (positionMin.z & -16)) { iterationChunkLocation.z = (positionMax.z & -16); iterationChunkLocation.x -= 16; if (iterationChunkLocation.x < (positionMin.x & -16)) { iterationChunkLocation.x = (positionMax.x & -16); iterationChunkLocation.y -= 16; if (iterationChunkLocation.y < (positionMin.y & -16)) { cursor = Vector3Int.invalidPos; return(false); } } } } cursor = IteratorHelper.ZOrderToPosition(iterationIndex).ToWorld(iterationChunkLocation); if (IsInBounds(cursor)) { return(true); } } }
void IOutput.Suggestion(string kind, APC pc, string suggestion, List <uint> causes) { var msg = String.Format("Suggestion: {0}", suggestion); // TODO: It would be better to have a different way to tell the issue provider // that this issue is related to the method as a whole and not any particular // location so that it could decide on what span to attach the issue to. var startIndex = 0; var length = 0; MethodReferenceAdaptor meth; var ok = pc.TryGetContainingMethod(out meth); if (ok && IteratorHelper.EnumerableIsNotEmpty(meth.reference.Locations)) { var l = IteratorHelper.First(meth.reference.Locations) as ISourceLocation; if (l != null) { startIndex = l.StartIndex; length = l.Length; } } this.results.Add(Tuple.Create(msg, new TextSpan(startIndex, length))); }
private void PrintTypeContract(ITypeContract /*?*/ typeContract) { if (typeContract == null || IteratorHelper.EnumerableIsEmpty(typeContract.Invariants)) { this.Indent(); Console.WriteLine("no invariant"); return; } foreach (var i in typeContract.Invariants) { Indent(); Console.Write("invariant "); if (!String.IsNullOrEmpty(i.OriginalSource)) { Console.Write(i.OriginalSource); } else { Console.Write(PrintExpression(i.Condition)); } Console.WriteLine(); } }
private static void InitializeArgumentsAndPushReturnResult(Instruction instruction, Stack <Instruction> stack, ISignature signature) { Contract.Requires(instruction != null); Contract.Requires(stack != null); Contract.Requires(signature != null); var numArguments = IteratorHelper.EnumerableCount(signature.Parameters); var arguments = new Instruction[numArguments]; instruction.Operand2 = arguments; for (var i = numArguments; i > 0; i--) { arguments[i - 1] = stack.Pop(); } if (!signature.IsStatic) { instruction.Operand1 = stack.Pop(); } if (signature.Type.TypeCode != PrimitiveTypeCode.Void) { stack.Push(instruction); } }
public bool MoveNext() { while (true) { iterationIndex++; if (iterationIndex >= 16 * 16 * 16) { iterationIndex = 0; iterationChunkLocation.z += 16; if (iterationChunkLocation.z > (positionMax.z & -16)) { iterationChunkLocation.z = (positionMin.z & -16); iterationChunkLocation.x += 16; if (iterationChunkLocation.x > (positionMax.x & -16)) { iterationChunkLocation.x = (positionMin.x & -16); iterationChunkLocation.y += 16; if (iterationChunkLocation.y > (positionMax.y & -16)) { return(false); } } } } cursor = IteratorHelper.ZOrderToPosition(iterationIndex).ToWorld(iterationChunkLocation); if (IsInBounds(cursor)) { return(true); } } }
private static void InitializeArgumentsAndPushReturnResult(Instruction instruction, Stack <Instruction> stack, ISignature signature) { Contract.Requires(instruction != null); Contract.Requires(stack != null); Contract.Requires(signature != null); var methodRef = signature as IMethodReference; uint numArguments = IteratorHelper.EnumerableCount(signature.Parameters); if (methodRef != null && methodRef.AcceptsExtraArguments) { numArguments += IteratorHelper.EnumerableCount(methodRef.ExtraParameters); } if (!signature.IsStatic) { numArguments++; } if (numArguments > 0) { numArguments--; if (numArguments > 0) { var arguments = new Instruction[numArguments]; instruction.Operand2 = arguments; for (var i = numArguments; i > 0; i--) { arguments[i - 1] = stack.Pop(); } } instruction.Operand1 = stack.Pop(); } if (signature.Type.TypeCode != PrimitiveTypeCode.Void) { stack.Push(instruction); } }
/// <summary> /// The constructor for creating an aggregating extractor. /// </summary> /// <param name="host">This is the host that loaded the unit for which the <paramref name="primaryExtractor"/> is /// the extractor for. /// </param> /// <param name="primaryExtractor"> /// The extractor that will be used to define the types/members of things referred to in contracts. /// </param> /// <param name="oobExtractorsAndHosts"> /// These are optional. If non-null, then it must be a finite sequence of pairs: each pair is a contract extractor /// and the host that loaded the unit for which it is a extractor. /// </param> public AggregatingContractExtractor(IMetadataHost host, IContractExtractor primaryExtractor, IEnumerable <KeyValuePair <IContractProvider, IMetadataHost> > /*?*/ oobExtractorsAndHosts) { var primaryUnit = primaryExtractor.Unit; this.unit = primaryUnit; this.primaryExtractor = primaryExtractor; this.underlyingContractProvider = new ContractProvider(primaryExtractor.ContractMethods, primaryUnit); this.host = host; if (oobExtractorsAndHosts != null && IteratorHelper.EnumerableIsNotEmpty(oobExtractorsAndHosts)) { this.oobExtractors = new List <IContractProvider>(); foreach (var oobProviderAndHost in oobExtractorsAndHosts) { var oobProvider = oobProviderAndHost.Key; var oobHost = oobProviderAndHost.Value; this.oobExtractors.Add(oobProvider); IUnit oobUnit = oobProvider.Unit; this.mapperForOobToPrimary.Add(oobProvider, new MappingMutator(host, primaryUnit, oobUnit)); this.mapperForPrimaryToOob.Add(oobProvider, new MappingMutator(oobHost, oobUnit, primaryUnit)); } } }
void CheckTypeSurface(ITypeDefinition type, INamedTypeDefinition original) { Contract.Requires(type != null); Contract.Requires(original != null); var baseClassCount = IteratorHelper.EnumerableCount(type.BaseClasses); var originalBaseClassCount = IteratorHelper.EnumerableCount(original.BaseClasses); if (baseClassCount != originalBaseClassCount) { Error("{0} has a different number of base classes in contract reference assembly.", TypeHelper.GetTypeName(type)); } else if (0 < baseClassCount) { var baseType = IteratorHelper.First(type.BaseClasses); Contract.Assume(baseType != null); var baseTypeName = TypeHelper.GetTypeName(baseType, NameFormattingOptions.UseGenericTypeNameSuffix); var originalBaseType = IteratorHelper.First(original.BaseClasses); Contract.Assume(originalBaseType != null); var originalName = TypeHelper.GetTypeName(originalBaseType, NameFormattingOptions.UseGenericTypeNameSuffix); if (!baseTypeName.Equals(originalName)) { // Warning instead of Error because existing contract assemblies have lots of violations and it // is a pain to chase each and every one down. Causes lots of new files/classes to be added for // each base class. this.Warning("{0} has a different base class in contract reference assembly. Should be {1} instead of {2}.", TypeHelper.GetTypeName(type), originalName, baseTypeName); } } foreach (var member in type.Members) { CheckSurface(member, original); } }
/// <summary> /// /// </summary> /// <param name="resource"></param> /// <param name="internFactory"></param> public void Copy(IResource resource, IInternFactory internFactory) { if (IteratorHelper.EnumerableIsNotEmpty(resource.Attributes)) { this.attributes = new List <ICustomAttribute>(resource.Attributes); } else { this.attributes = null; } this.data = new List <byte>(resource.Data); this.definingAssembly = resource.DefiningAssembly; if (resource.IsInExternalFile) { this.externalFile = resource.ExternalFile; } else { this.externalFile = Dummy.FileReference; } this.isInExternalFile = resource.IsInExternalFile; this.isPublic = resource.IsPublic; this.name = resource.Name; }
/// <summary> /// /// </summary> /// <param name="instruction"></param> protected virtual void EmitOperationFor(Instruction instruction) { Contract.Requires(instruction != null); var operation = instruction.Operation; switch (operation.OperationCode) { case OperationCode.Arglist: case OperationCode.Dup: case OperationCode.Ldc_I4: case OperationCode.Ldc_I4_0: case OperationCode.Ldc_I4_1: case OperationCode.Ldc_I4_2: case OperationCode.Ldc_I4_3: case OperationCode.Ldc_I4_4: case OperationCode.Ldc_I4_5: case OperationCode.Ldc_I4_6: case OperationCode.Ldc_I4_7: case OperationCode.Ldc_I4_8: case OperationCode.Ldc_I4_M1: case OperationCode.Ldc_I4_S: case OperationCode.Ldc_I8: case OperationCode.Ldc_R4: case OperationCode.Ldc_R8: case OperationCode.Ldftn: case OperationCode.Ldnull: case OperationCode.Ldsfld: case OperationCode.Ldsflda: case OperationCode.Ldstr: case OperationCode.Ldtoken: this.StackHeight += 1; break; case OperationCode.Add: case OperationCode.Add_Ovf: case OperationCode.Add_Ovf_Un: case OperationCode.And: case OperationCode.Ceq: case OperationCode.Cgt: case OperationCode.Cgt_Un: case OperationCode.Clt: case OperationCode.Clt_Un: case OperationCode.Div: case OperationCode.Div_Un: case OperationCode.Initobj: case OperationCode.Ldelem: case OperationCode.Ldelem_I: case OperationCode.Ldelem_I1: case OperationCode.Ldelem_I2: case OperationCode.Ldelem_I4: case OperationCode.Ldelem_I8: case OperationCode.Ldelem_R4: case OperationCode.Ldelem_R8: case OperationCode.Ldelem_Ref: case OperationCode.Ldelem_U1: case OperationCode.Ldelem_U2: case OperationCode.Ldelem_U4: case OperationCode.Ldelema: case OperationCode.Mkrefany: case OperationCode.Mul: case OperationCode.Mul_Ovf: case OperationCode.Mul_Ovf_Un: case OperationCode.Or: case OperationCode.Pop: case OperationCode.Rem: case OperationCode.Rem_Un: case OperationCode.Shl: case OperationCode.Shr: case OperationCode.Shr_Un: case OperationCode.Stsfld: case OperationCode.Sub: case OperationCode.Sub_Ovf: case OperationCode.Sub_Ovf_Un: case OperationCode.Switch: case OperationCode.Throw: case OperationCode.Xor: this.StackHeight -= 1; break; case OperationCode.Array_Addr: case OperationCode.Array_Get: Contract.Assume(operation.Value is IArrayTypeReference); var arrayType = (IArrayTypeReference)operation.Value; this.StackHeight -= arrayType.Rank; break; case OperationCode.Array_Set: Contract.Assume(operation.Value is IArrayTypeReference); arrayType = (IArrayTypeReference)operation.Value; this.StackHeight -= arrayType.Rank + 1; break; case OperationCode.Array_Create: Contract.Assume(operation.Value is IArrayTypeReference); arrayType = (IArrayTypeReference)operation.Value; this.StackHeight -= arrayType.Rank - 1; break; case OperationCode.Array_Create_WithLowerBound: Contract.Assume(operation.Value is IArrayTypeReference); arrayType = (IArrayTypeReference)operation.Value; this.StackHeight -= arrayType.Rank * 2 - 1; break; case OperationCode.Br: case OperationCode.Br_S: case OperationCode.Leave: case OperationCode.Leave_S: Contract.Assume(operation.Value is uint); this.ilGenerator.Emit(operation.OperationCode, this.GetLabelFor((uint)operation.Value)); return; case OperationCode.Beq: case OperationCode.Beq_S: case OperationCode.Bge: case OperationCode.Bge_S: case OperationCode.Bge_Un: case OperationCode.Bge_Un_S: case OperationCode.Bgt: case OperationCode.Bgt_S: case OperationCode.Bgt_Un: case OperationCode.Bgt_Un_S: case OperationCode.Ble: case OperationCode.Ble_S: case OperationCode.Ble_Un: case OperationCode.Ble_Un_S: case OperationCode.Blt: case OperationCode.Blt_S: case OperationCode.Blt_Un: case OperationCode.Blt_Un_S: case OperationCode.Bne_Un: case OperationCode.Bne_Un_S: this.StackHeight -= 2; Contract.Assume(operation.Value is uint); this.ilGenerator.Emit(operation.OperationCode, this.GetLabelFor((uint)operation.Value)); return; case OperationCode.Brfalse: case OperationCode.Brfalse_S: case OperationCode.Brtrue: case OperationCode.Brtrue_S: this.StackHeight -= 1; Contract.Assume(operation.Value is uint); this.ilGenerator.Emit(operation.OperationCode, this.GetLabelFor((uint)operation.Value)); return; case OperationCode.Call: case OperationCode.Calli: case OperationCode.Callvirt: case OperationCode.Newobj: Contract.Assume(operation.Value is ISignature); var signature = (ISignature)operation.Value; var adjustment = IteratorHelper.EnumerableCount(signature.Parameters); if (operation.OperationCode == OperationCode.Newobj) { adjustment--; } else { if (operation.OperationCode == OperationCode.Calli) { adjustment++; } if (!signature.IsStatic) { adjustment++; } if (signature.Type.TypeCode != PrimitiveTypeCode.Void) { adjustment--; } } this.StackHeight -= adjustment; break; case OperationCode.Cpobj: case OperationCode.Stfld: case OperationCode.Stind_I: case OperationCode.Stind_I1: case OperationCode.Stind_I2: case OperationCode.Stind_I4: case OperationCode.Stind_I8: case OperationCode.Stind_R4: case OperationCode.Stind_R8: case OperationCode.Stind_Ref: case OperationCode.Stobj: this.StackHeight -= 2; break; case OperationCode.Cpblk: case OperationCode.Initblk: case OperationCode.Stelem: case OperationCode.Stelem_I: case OperationCode.Stelem_I1: case OperationCode.Stelem_I2: case OperationCode.Stelem_I4: case OperationCode.Stelem_I8: case OperationCode.Stelem_R4: case OperationCode.Stelem_R8: case OperationCode.Stelem_Ref: this.StackHeight -= 3; break; case OperationCode.Ldarg: case OperationCode.Ldarg_0: case OperationCode.Ldarg_1: case OperationCode.Ldarg_2: case OperationCode.Ldarg_3: case OperationCode.Ldarg_S: this.StackHeight += 1; this.LoadParameter(operation.Value as IParameterDefinition); return; case OperationCode.Ldarga: case OperationCode.Ldarga_S: this.StackHeight += 1; this.LoadParameterAddress(operation.Value as IParameterDefinition); return; case OperationCode.Ldloc: case OperationCode.Ldloc_0: case OperationCode.Ldloc_1: case OperationCode.Ldloc_2: case OperationCode.Ldloc_3: case OperationCode.Ldloc_S: this.StackHeight += 1; Contract.Assume(operation.Value is ILocalDefinition); this.LoadLocal((ILocalDefinition)operation.Value); return; case OperationCode.Ldloca: case OperationCode.Ldloca_S: this.StackHeight += 1; Contract.Assume(operation.Value is ILocalDefinition); LoadLocalAddress((ILocalDefinition)operation.Value); return; case OperationCode.Starg: case OperationCode.Starg_S: this.StackHeight -= 1; this.StoreParameter(operation.Value as IParameterDefinition); return; case OperationCode.Stloc: case OperationCode.Stloc_0: case OperationCode.Stloc_1: case OperationCode.Stloc_2: case OperationCode.Stloc_3: case OperationCode.Stloc_S: this.StackHeight -= 1; Contract.Assume(operation.Value is ILocalDefinition); this.StoreLocal((ILocalDefinition)operation.Value); return; case OperationCode.Box: case OperationCode.Break: case OperationCode.Castclass: case OperationCode.Ckfinite: case OperationCode.Constrained_: case OperationCode.Conv_I: case OperationCode.Conv_I1: case OperationCode.Conv_I2: case OperationCode.Conv_I4: case OperationCode.Conv_I8: case OperationCode.Conv_Ovf_I: case OperationCode.Conv_Ovf_I_Un: case OperationCode.Conv_Ovf_I1: case OperationCode.Conv_Ovf_I1_Un: case OperationCode.Conv_Ovf_I2: case OperationCode.Conv_Ovf_I2_Un: case OperationCode.Conv_Ovf_I4: case OperationCode.Conv_Ovf_I4_Un: case OperationCode.Conv_Ovf_I8: case OperationCode.Conv_Ovf_I8_Un: case OperationCode.Conv_Ovf_U: case OperationCode.Conv_Ovf_U_Un: case OperationCode.Conv_Ovf_U1: case OperationCode.Conv_Ovf_U1_Un: case OperationCode.Conv_Ovf_U2: case OperationCode.Conv_Ovf_U2_Un: case OperationCode.Conv_Ovf_U4: case OperationCode.Conv_Ovf_U4_Un: case OperationCode.Conv_Ovf_U8: case OperationCode.Conv_Ovf_U8_Un: case OperationCode.Conv_R_Un: case OperationCode.Conv_R4: case OperationCode.Conv_R8: case OperationCode.Conv_U: case OperationCode.Conv_U1: case OperationCode.Conv_U2: case OperationCode.Conv_U4: case OperationCode.Conv_U8: case OperationCode.Endfilter: case OperationCode.Endfinally: case OperationCode.Isinst: case OperationCode.Jmp: case OperationCode.Ldfld: case OperationCode.Ldflda: case OperationCode.Ldind_I: case OperationCode.Ldind_I1: case OperationCode.Ldind_I2: case OperationCode.Ldind_I4: case OperationCode.Ldind_I8: case OperationCode.Ldind_R4: case OperationCode.Ldind_R8: case OperationCode.Ldind_Ref: case OperationCode.Ldind_U1: case OperationCode.Ldind_U2: case OperationCode.Ldind_U4: case OperationCode.Ldlen: case OperationCode.Ldobj: case OperationCode.Ldvirtftn: case OperationCode.Localloc: case OperationCode.Neg: case OperationCode.Newarr: case OperationCode.No_: case OperationCode.Nop: case OperationCode.Not: case OperationCode.Readonly_: case OperationCode.Refanytype: case OperationCode.Refanyval: case OperationCode.Rethrow: case OperationCode.Sizeof: case OperationCode.Tail_: case OperationCode.Unaligned_: case OperationCode.Unbox: case OperationCode.Unbox_Any: case OperationCode.Volatile_: break; case OperationCode.Ret: if (this.Cdfg.MethodBody.MethodDefinition.Type.TypeCode != PrimitiveTypeCode.Void) { this.StackHeight -= 1; } break; default: Contract.Assume(false); break; } this.ilGenerator.Emit(operation.OperationCode, operation.Value); }
public virtual void PrintMethodDefinitionModifiers(IMethodDefinition methodDefinition) { Contract.Requires(methodDefinition != null); // This algorithm is probably not exactly right yet. // TODO: Compare to FrameworkDesignStudio rules (see CCIModifiers project, and AssemblyDocumentWriter.WriteMemberStart) if (IsMethodUnsafe(methodDefinition)) { PrintKeywordUnsafe(); } if (!(Utils.GetHiddenBaseClassMethod(methodDefinition) is Dummy)) { PrintKeywordNew(); } if (methodDefinition.ContainingTypeDefinition.IsInterface) { // Defining an interface method - 'unsafe' and 'new' are the only valid modifier return; } if (!methodDefinition.IsAbstract && methodDefinition.IsExternal) { PrintKeywordExtern(); } if (IsDestructor(methodDefinition)) { return; } if (methodDefinition.IsStatic) { PrintKeywordStatic(); } else if (methodDefinition.IsVirtual) { if (methodDefinition.IsNewSlot && (IteratorHelper.EnumerableIsNotEmpty(MemberHelper.GetImplicitlyImplementedInterfaceMethods(methodDefinition)) || IteratorHelper.EnumerableIsNotEmpty(MemberHelper.GetExplicitlyOverriddenMethods(methodDefinition)))) { // Implementing a method defined on an interface: implicitly virtual and sealed if (methodDefinition.IsAbstract) { PrintKeywordAbstract(); } else if (!methodDefinition.IsSealed) { PrintKeywordVirtual(); } } else { // Instance method on a class if (methodDefinition.IsAbstract) { PrintKeywordAbstract(); } if (methodDefinition.IsNewSlot) { // Only overrides (or interface impls) can be sealed in C#. If this is // a new sealed virtual then just emit as non-virtual which is a similar thing. // We get these in reference assemblies for methods which were implementations of private (and so removed) // interfaces. if (!methodDefinition.IsSealed && !methodDefinition.IsAbstract) { PrintKeywordVirtual(); } } else { PrintKeywordOverride(); if (methodDefinition.IsSealed) { PrintKeywordSealed(); } } } } }
public override void TraverseChildren(IPropertyDefinition propertyDefinition) { PrintAttributes(propertyDefinition); bool isIndexer = false; if (IteratorHelper.EnumerableIsNotEmpty(propertyDefinition.Parameters)) { // We have an indexer. Note that this could still be an explicit interface implementation. // If it's got a name other than 'Item', we need an attribute to rename it. // Note that there will usually be a DefaultMemberAttribute on the class with the name // but the attribute doesn't always exist (eg. if it's an explicit interaface impl) isIndexer = true; string id = propertyDefinition.Name.Value; string simpleId = id.Substring(id.LastIndexOf('.') + 1); // excludes any interface type if (simpleId != "Item") { PrintPseudoCustomAttribute(propertyDefinition, "System.Runtime.CompilerServices.IndexerName", QuoteString(simpleId), true, null); } } PrintToken(CSharpToken.Indent); IMethodDefinition propMeth = propertyDefinition.Getter == null ? propertyDefinition.Setter.ResolvedMethod : propertyDefinition.Getter.ResolvedMethod; if (!propertyDefinition.ContainingTypeDefinition.IsInterface && IteratorHelper.EnumerableIsEmpty(MemberHelper.GetExplicitlyOverriddenMethods(propMeth))) { PrintPropertyDefinitionVisibility(propertyDefinition); } PrintPropertyDefinitionModifiers(propertyDefinition); PrintPropertyDefinitionReturnType(propertyDefinition); PrintToken(CSharpToken.Space); if (isIndexer) { // Indexers are always identified with a 'this' keyword, but might have an interface prefix string id = propertyDefinition.Name.Value; int lastDot = id.LastIndexOf('.'); if (lastDot != -1) { sourceEmitterOutput.Write(id.Substring(0, lastDot + 1)); } PrintToken(CSharpToken.This); PrintToken(CSharpToken.LeftSquareBracket); bool fFirstParameter = true; var parms = propertyDefinition.Parameters; if (propertyDefinition.Getter != null) { parms = propertyDefinition.Getter.ResolvedMethod.Parameters; // more likely to have names } else if (propertyDefinition.Setter != null) { // Use the setter's names except for the final 'value' parameter var l = new List <IParameterDefinition>(propertyDefinition.Setter.ResolvedMethod.Parameters); l.RemoveAt(l.Count - 1); parms = l; } foreach (IParameterDefinition parameterDefinition in parms) { if (!fFirstParameter) { PrintParameterListDelimiter(); } this.Traverse(parameterDefinition); fFirstParameter = false; } PrintToken(CSharpToken.RightSquareBracket); } else { PrintPropertyDefinitionName(propertyDefinition); } PrintToken(CSharpToken.LeftCurly); if (propertyDefinition.Getter != null) { PrintToken(CSharpToken.Indent); var getMeth = propertyDefinition.Getter.ResolvedMethod; if (getMeth.Visibility != propertyDefinition.Visibility) { PrintTypeMemberVisibility(getMeth.Visibility); } PrintToken(CSharpToken.Get); if (getMeth.IsAbstract || getMeth.IsExternal) { PrintToken(CSharpToken.Semicolon); } else { Traverse(getMeth.Body); } } if (propertyDefinition.Setter != null) { PrintToken(CSharpToken.Indent); var setMeth = propertyDefinition.Setter.ResolvedMethod; if (setMeth.Visibility != propertyDefinition.Visibility) { PrintTypeMemberVisibility(setMeth.Visibility); } PrintToken(CSharpToken.Set); if (setMeth.IsAbstract || setMeth.IsExternal) { PrintToken(CSharpToken.Semicolon); } else { Traverse(setMeth.Body); } } PrintToken(CSharpToken.RightCurly); }
private NamedTypeDefinition TranslateMetadata(INamedTypeSymbol typeSymbol) { Contract.Requires(typeSymbol != null); Contract.Ensures(Contract.Result <NamedTypeDefinition>() != null); NamedTypeDefinition cciType; ITypeReference cciTypeRef; if (this.typeSymbolCache.TryGetValue(typeSymbol, out cciTypeRef)) { cciType = (NamedTypeDefinition)cciTypeRef; } else { cciType = CreateTypeDefinition(typeSymbol); } this.module.AllTypes.Add(cciType); var mems = new List <ITypeDefinitionMember>(); foreach (var m in typeSymbol.GetMembers()) { var attributes = this.TranslateMetadata(m.GetAttributes()); switch (m.Kind) { case SymbolKind.Field: var field = TranslateMetadata(m as IFieldSymbol); field.Attributes = attributes; if (cciType.Fields == null) { cciType.Fields = new List <IFieldDefinition>(); } cciType.Fields.Add(field); break; case SymbolKind.Method: var methodSymbol = m as IMethodSymbol; var meth = TranslateMetadata(methodSymbol); meth.Attributes = attributes; if (cciType.Methods == null) { cciType.Methods = new List <IMethodDefinition>(); } cciType.Methods.Add(meth); break; case SymbolKind.NamedType: var namedType = TranslateMetadata((INamedTypeSymbol)m); Contract.Assert(namedType is NestedTypeDefinition); var nestedType = (NestedTypeDefinition)namedType; nestedType.Attributes = attributes; if (cciType.NestedTypes == null) { cciType.NestedTypes = new List <INestedTypeDefinition>(); } cciType.NestedTypes.Add((NestedTypeDefinition)nestedType); break; case SymbolKind.Property: var property = TranslateMetadata(m as IPropertySymbol); property.Attributes = attributes; if (cciType.Properties == null) { cciType.Properties = new List <IPropertyDefinition>(); } cciType.Properties.Add(property); break; default: throw new NotImplementedException(); } } if (typeSymbol.IsValueType) { cciType.Layout = LayoutKind.Sequential; if (IteratorHelper.EnumerableIsEmpty(cciType.Fields)) { cciType.SizeOf = 1; } } return(cciType); }
public override void TraverseChildren(IMethodCall methodCall) { var resolvedMethod = Sink.Unspecialize(methodCall.MethodToCall).ResolvedMethod; var methodName = Microsoft.Cci.MemberHelper.GetMethodSignature(resolvedMethod); if (methodName.Equals("System.Object.GetHashCode") || methodName.Equals("System.Object.ToString")) { base.TraverseChildren(methodCall); return; } bool isEventAdd = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("add_"); bool isEventRemove = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("remove_"); if (isEventAdd || isEventRemove) { base.TraverseChildren(methodCall); return; } if (!methodCall.IsVirtualCall) { base.TraverseChildren(methodCall); return; } var containingType = TypeHelper.UninstantiateAndUnspecialize(methodCall.MethodToCall.ContainingType); List <ITypeReference> subTypesOfContainingType; if (!this.subTypes.TryGetValue(containingType, out subTypesOfContainingType)) { base.TraverseChildren(methodCall); return; } Contract.Assert(0 < subTypesOfContainingType.Count); Contract.Assert(!methodCall.IsStaticCall); Contract.Assert(!resolvedMethod.IsConstructor); var overrides = FindOverrides(containingType, resolvedMethod); bool same = true; foreach (var o in overrides) { IMethodDefinition resolvedOverride = Sink.Unspecialize(o.Item2).ResolvedMethod; if (resolvedOverride != resolvedMethod) { same = false; } } if (!(containingType.ResolvedType.IsInterface) && (0 == overrides.Count || same)) { base.TraverseChildren(methodCall); return; } Contract.Assume(1 <= overrides.Count); var getType = new Microsoft.Cci.MethodReference( this.sink.host, this.sink.host.PlatformType.SystemObject, CallingConvention.HasThis, this.sink.host.PlatformType.SystemType, this.sink.host.NameTable.GetNameFor("GetType"), 0); var op_Type_Equality = new Microsoft.Cci.MethodReference( this.sink.host, this.sink.host.PlatformType.SystemType, CallingConvention.Default, this.sink.host.PlatformType.SystemBoolean, this.sink.host.NameTable.GetNameFor("op_Equality"), 0, this.sink.host.PlatformType.SystemType, this.sink.host.PlatformType.SystemType); // Depending on whether the method is a void method or not // Turn into expression: // (o.GetType() == typeof(T1)) ? ((T1)o).M(...) : ( (o.GetType() == typeof(T2)) ? ((T2)o).M(...) : ... // Or turn into statements: // if (o.GetType() == typeof(T1)) ((T1)o).M(...) else if ... var turnIntoStatements = resolvedMethod.Type.TypeCode == PrimitiveTypeCode.Void; IStatement elseStatement = null; IExpression elseValue = new MethodCall() { Arguments = new List <IExpression>(methodCall.Arguments), IsStaticCall = false, IsVirtualCall = false, MethodToCall = methodCall.MethodToCall, ThisArgument = methodCall.ThisArgument, Type = methodCall.Type, }; if (turnIntoStatements) { elseStatement = new ExpressionStatement() { Expression = elseValue, } } ; Conditional ifConditional = null; ConditionalStatement ifStatement = null; foreach (var typeMethodPair in overrides) { var t = typeMethodPair.Item1; var m = typeMethodPair.Item2; if (m.IsGeneric) { var baseMethod = m.ResolvedMethod; m = new GenericMethodInstanceReference() { CallingConvention = baseMethod.CallingConvention, ContainingType = baseMethod.ContainingTypeDefinition, GenericArguments = new List <ITypeReference>(IteratorHelper.GetConversionEnumerable <IGenericMethodParameter, ITypeReference>(baseMethod.GenericParameters)), GenericMethod = baseMethod, InternFactory = this.sink.host.InternFactory, Name = baseMethod.Name, Parameters = baseMethod.ParameterCount == 0 ? null : new List <IParameterTypeInformation>(baseMethod.Parameters), Type = baseMethod.Type, }; } var cond = new MethodCall() { Arguments = new List <IExpression>() { new MethodCall() { Arguments = new List <IExpression>(), IsStaticCall = false, IsVirtualCall = false, MethodToCall = getType, ThisArgument = methodCall.ThisArgument, }, new TypeOf() { TypeToGet = t, }, }, IsStaticCall = true, IsVirtualCall = false, MethodToCall = op_Type_Equality, Type = this.sink.host.PlatformType.SystemBoolean, }; Expression thenValue = new MethodCall() { Arguments = new List <IExpression>(methodCall.Arguments), IsStaticCall = false, IsVirtualCall = false, MethodToCall = m, ThisArgument = methodCall.ThisArgument, Type = m.Type, }; thenValue = new Conversion() { Type = m.Type, TypeAfterConversion = methodCall.Type, ValueToConvert = thenValue, }; if (turnIntoStatements) { ifStatement = new ConditionalStatement() { Condition = cond, FalseBranch = elseStatement, TrueBranch = new ExpressionStatement() { Expression = thenValue, }, }; elseStatement = ifStatement; } else { ifConditional = new Conditional() { Condition = cond, ResultIfFalse = elseValue, ResultIfTrue = thenValue, }; elseValue = ifConditional; } } if (turnIntoStatements) { Contract.Assume(ifStatement != null); this.StmtTraverser.Traverse(ifStatement); } else { Contract.Assume(ifConditional != null); base.Traverse(ifConditional); } return; }
public static bool SignaturesParametersAreEqual(this ISignature sig1, ISignature sig2) { return(IteratorHelper.EnumerablesAreEqual <IParameterTypeInformation>(sig1.Parameters, sig2.Parameters, new ParameterInformationComparer())); }
// makes a copy of the method public void copyMethod(MethodDefinition dest, IMethodDefinition source) { // only copy body if it is not a dummy (= empty) if (!(source.Body is Microsoft.Cci.Dummy)) { // copy instructions ILGenerator ilGenerator = new ILGenerator(this.host, dest); foreach (var operation in source.Body.Operations) { ilGenerator.Emit(operation.OperationCode, operation.Value); } // copy the exception handler foreach (IOperationExceptionInformation exceptionToCopy in source.Body.OperationExceptionInformation) { ILGeneratorLabel tryStart = new ILGeneratorLabel(); tryStart.Offset = exceptionToCopy.TryStartOffset; ILGeneratorLabel tryEnd = new ILGeneratorLabel(); tryEnd.Offset = exceptionToCopy.TryEndOffset; ILGeneratorLabel handlerStart = new ILGeneratorLabel(); handlerStart.Offset = exceptionToCopy.HandlerStartOffset; ILGeneratorLabel handlerEnd = new ILGeneratorLabel(); handlerEnd.Offset = exceptionToCopy.HandlerEndOffset; ILGeneratorLabel filterStart = new ILGeneratorLabel(); filterStart.Offset = exceptionToCopy.FilterDecisionStartOffset; ilGenerator.AddExceptionHandlerInformation(exceptionToCopy.HandlerKind, exceptionToCopy.ExceptionType, tryStart, tryEnd, handlerStart, handlerEnd, filterStart); } // create the body List <ILocalDefinition> variableListCopy = new List <ILocalDefinition>(source.Body.LocalVariables); List <ITypeDefinition> privateHelperTypesListCopy = new List <ITypeDefinition>(source.Body.PrivateHelperTypes); var newBody = new ILGeneratorMethodBody(ilGenerator, source.Body.LocalsAreZeroed, source.Body.MaxStack, dest, variableListCopy, privateHelperTypesListCopy); dest.Body = newBody; } dest.CallingConvention = source.CallingConvention; if (source.IsGeneric) { dest.GenericParameters = new List <IGenericMethodParameter>(source.GenericParameters); } else { dest.GenericParameters = null; } if (source.ParameterCount > 0) { dest.Parameters = new List <IParameterDefinition>(source.Parameters); } else { dest.Parameters = null; } if (source.IsPlatformInvoke) { dest.PlatformInvokeData = source.PlatformInvokeData; } else { dest.PlatformInvokeData = Dummy.PlatformInvokeInformation; } dest.ReturnValueAttributes = new List <ICustomAttribute>(source.ReturnValueAttributes); if (source.ReturnValueIsModified) { dest.ReturnValueCustomModifiers = new List <ICustomModifier>(source.ReturnValueCustomModifiers); } else { dest.ReturnValueCustomModifiers = new List <ICustomModifier>(0); } if (source.ReturnValueIsMarshalledExplicitly) { dest.ReturnValueMarshallingInformation = source.ReturnValueMarshallingInformation; } else { dest.ReturnValueMarshallingInformation = Dummy.MarshallingInformation; } if (source.HasDeclarativeSecurity && IteratorHelper.EnumerableIsNotEmpty(source.SecurityAttributes)) { dest.SecurityAttributes = new List <ISecurityAttribute>(source.SecurityAttributes); } else { dest.SecurityAttributes = null; } dest.Type = source.Type; dest.AcceptsExtraArguments = source.AcceptsExtraArguments; dest.HasDeclarativeSecurity = source.HasDeclarativeSecurity; dest.IsAbstract = source.IsAbstract; dest.IsAccessCheckedOnOverride = source.IsAccessCheckedOnOverride; dest.IsCil = source.IsCil; dest.IsExternal = source.IsExternal; dest.IsForwardReference = source.IsForwardReference; dest.IsHiddenBySignature = source.IsHiddenBySignature; dest.IsNativeCode = source.IsNativeCode; dest.IsNewSlot = source.IsNewSlot; dest.IsNeverInlined = source.IsNeverInlined; dest.IsAggressivelyInlined = source.IsAggressivelyInlined; dest.IsNeverOptimized = source.IsNeverOptimized; dest.IsPlatformInvoke = source.IsPlatformInvoke; dest.IsRuntimeImplemented = source.IsRuntimeImplemented; dest.IsRuntimeInternal = source.IsRuntimeInternal; dest.IsRuntimeSpecial = source.IsRuntimeSpecial; dest.IsSealed = source.IsSealed; dest.IsSpecialName = source.IsSpecialName; dest.IsStatic = source.IsStatic; dest.IsSynchronized = source.IsSynchronized; dest.IsUnmanaged = source.IsUnmanaged; if (dest.IsStatic) { dest.IsVirtual = false; } else { dest.IsVirtual = source.IsVirtual; } dest.PreserveSignature = source.PreserveSignature; dest.RequiresSecurityObject = source.RequiresSecurityObject; dest.ReturnValueIsByRef = source.ReturnValueIsByRef; dest.ReturnValueIsMarshalledExplicitly = source.ReturnValueIsMarshalledExplicitly; dest.ReturnValueName = source.ReturnValueName; dest.Name = source.Name; dest.Visibility = source.Visibility; }
public override IMethodBody Rewrite(IMethodBody methodBody) { this.cdfg = ControlAndDataFlowGraph <BasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(this.host, methodBody); this.ilGenerator = new ILGenerator(host, methodBody.MethodDefinition); var numberOfBlocks = this.cdfg.BlockFor.Count; this.labelFor = new Hashtable <ILGeneratorLabel>(numberOfBlocks); this.counterFieldsForCurrentMethod = new NestedTypeDefinition() { BaseClasses = new List <ITypeReference>(1) { this.host.PlatformType.SystemObject }, ContainingTypeDefinition = methodBody.MethodDefinition.ContainingTypeDefinition, Fields = new List <IFieldDefinition>((int)numberOfBlocks * 2), Methods = new List <IMethodDefinition>(1), InternFactory = this.host.InternFactory, IsBeforeFieldInit = true, IsClass = true, IsSealed = true, IsAbstract = true, Name = this.host.NameTable.GetNameFor(methodBody.MethodDefinition.Name + "_Counters" + methodBody.MethodDefinition.InternedKey), Visibility = TypeMemberVisibility.Assembly, }; this.fieldOffsets = new List <uint>((int)numberOfBlocks * 2); foreach (var exceptionInfo in methodBody.OperationExceptionInformation) { this.ilGenerator.AddExceptionHandlerInformation(exceptionInfo.HandlerKind, exceptionInfo.ExceptionType, this.GetLabelFor(exceptionInfo.TryStartOffset), this.GetLabelFor(exceptionInfo.TryEndOffset), this.GetLabelFor(exceptionInfo.HandlerStartOffset), this.GetLabelFor(exceptionInfo.HandlerEndOffset), exceptionInfo.HandlerKind == HandlerKind.Filter ? this.GetLabelFor(exceptionInfo.FilterDecisionStartOffset) : null); } if (this.pdbReader == null) { foreach (var localDef in methodBody.LocalVariables) { this.ilGenerator.AddVariableToCurrentScope(localDef); } } else { foreach (var ns in this.pdbReader.GetNamespaceScopes(methodBody)) { foreach (var uns in ns.UsedNamespaces) { this.ilGenerator.UseNamespace(uns.NamespaceName.Value); } } this.scopeEnumerator = this.pdbReader.GetLocalScopes(methodBody).GetEnumerator(); this.scopeEnumeratorIsValid = this.scopeEnumerator.MoveNext(); } foreach (var block in this.cdfg.AllBlocks) { this.InstrumentBlock(block); } while (this.scopeStack.Count > 0) { this.ilGenerator.EndScope(); this.scopeStack.Pop(); } this.ilGenerator.AdjustBranchSizesToBestFit(); this.InjectMethodToDumpCounters(); return(new ILGeneratorMethodBody(this.ilGenerator, methodBody.LocalsAreZeroed, (ushort)(methodBody.MaxStack + 2), methodBody.MethodDefinition, methodBody.LocalVariables, IteratorHelper.GetSingletonEnumerable((ITypeDefinition)this.counterFieldsForCurrentMethod))); }
private void SetupDataFlowFor(Instruction instruction) { Contract.Requires(instruction != null); switch (instruction.Operation.OperationCode) { case OperationCode.Add: case OperationCode.Add_Ovf: case OperationCode.Add_Ovf_Un: case OperationCode.And: case OperationCode.Ceq: case OperationCode.Cgt: case OperationCode.Cgt_Un: case OperationCode.Clt: case OperationCode.Clt_Un: case OperationCode.Div: case OperationCode.Div_Un: case OperationCode.Ldelema: case OperationCode.Ldelem: case OperationCode.Ldelem_I: case OperationCode.Ldelem_I1: case OperationCode.Ldelem_I2: case OperationCode.Ldelem_I4: case OperationCode.Ldelem_I8: case OperationCode.Ldelem_R4: case OperationCode.Ldelem_R8: case OperationCode.Ldelem_Ref: case OperationCode.Ldelem_U1: case OperationCode.Ldelem_U2: case OperationCode.Ldelem_U4: case OperationCode.Mul: case OperationCode.Mul_Ovf: case OperationCode.Mul_Ovf_Un: case OperationCode.Or: case OperationCode.Rem: case OperationCode.Rem_Un: case OperationCode.Shl: case OperationCode.Shr: case OperationCode.Shr_Un: case OperationCode.Sub: case OperationCode.Sub_Ovf: case OperationCode.Sub_Ovf_Un: case OperationCode.Xor: instruction.Operand2 = this.stack.Pop(); instruction.Operand1 = this.stack.Pop(); this.stack.Push(instruction); break; case OperationCode.Arglist: case OperationCode.Ldarg: case OperationCode.Ldarg_0: case OperationCode.Ldarg_1: case OperationCode.Ldarg_2: case OperationCode.Ldarg_3: case OperationCode.Ldarg_S: case OperationCode.Ldloc: case OperationCode.Ldloc_0: case OperationCode.Ldloc_1: case OperationCode.Ldloc_2: case OperationCode.Ldloc_3: case OperationCode.Ldloc_S: case OperationCode.Ldsfld: case OperationCode.Ldarga: case OperationCode.Ldarga_S: case OperationCode.Ldsflda: case OperationCode.Ldloca: case OperationCode.Ldloca_S: case OperationCode.Ldftn: case OperationCode.Ldc_I4: case OperationCode.Ldc_I4_0: case OperationCode.Ldc_I4_1: case OperationCode.Ldc_I4_2: case OperationCode.Ldc_I4_3: case OperationCode.Ldc_I4_4: case OperationCode.Ldc_I4_5: case OperationCode.Ldc_I4_6: case OperationCode.Ldc_I4_7: case OperationCode.Ldc_I4_8: case OperationCode.Ldc_I4_M1: case OperationCode.Ldc_I4_S: case OperationCode.Ldc_I8: case OperationCode.Ldc_R4: case OperationCode.Ldc_R8: case OperationCode.Ldnull: case OperationCode.Ldstr: case OperationCode.Ldtoken: case OperationCode.Sizeof: this.stack.Push(instruction); break; case OperationCode.Array_Addr: case OperationCode.Array_Get: Contract.Assume(instruction.Operation.Value is IArrayTypeReference); //This is an informally specified property of the Metadata model. InitializeArrayIndexerInstruction(instruction, this.stack, (IArrayTypeReference)instruction.Operation.Value); break; case OperationCode.Array_Create: case OperationCode.Array_Create_WithLowerBound: case OperationCode.Newarr: InitializeArrayCreateInstruction(instruction, this.stack, instruction.Operation); break; case OperationCode.Array_Set: Contract.Assume(instruction.Operation.Value is IArrayTypeReference); //This is an informally specified property of the Metadata model. InitializeArraySetInstruction(instruction, this.stack, (IArrayTypeReference)instruction.Operation.Value); break; case OperationCode.Beq: case OperationCode.Beq_S: case OperationCode.Bge: case OperationCode.Bge_S: case OperationCode.Bge_Un: case OperationCode.Bge_Un_S: case OperationCode.Bgt: case OperationCode.Bgt_S: case OperationCode.Bgt_Un: case OperationCode.Bgt_Un_S: case OperationCode.Ble: case OperationCode.Ble_S: case OperationCode.Ble_Un: case OperationCode.Ble_Un_S: case OperationCode.Blt: case OperationCode.Blt_S: case OperationCode.Blt_Un: case OperationCode.Blt_Un_S: case OperationCode.Bne_Un: case OperationCode.Bne_Un_S: instruction.Operand2 = this.stack.Pop(); instruction.Operand1 = this.stack.Pop(); break; case OperationCode.Box: case OperationCode.Castclass: case OperationCode.Ckfinite: case OperationCode.Conv_I: case OperationCode.Conv_I1: case OperationCode.Conv_I2: case OperationCode.Conv_I4: case OperationCode.Conv_I8: case OperationCode.Conv_Ovf_I: case OperationCode.Conv_Ovf_I_Un: case OperationCode.Conv_Ovf_I1: case OperationCode.Conv_Ovf_I1_Un: case OperationCode.Conv_Ovf_I2: case OperationCode.Conv_Ovf_I2_Un: case OperationCode.Conv_Ovf_I4: case OperationCode.Conv_Ovf_I4_Un: case OperationCode.Conv_Ovf_I8: case OperationCode.Conv_Ovf_I8_Un: case OperationCode.Conv_Ovf_U: case OperationCode.Conv_Ovf_U_Un: case OperationCode.Conv_Ovf_U1: case OperationCode.Conv_Ovf_U1_Un: case OperationCode.Conv_Ovf_U2: case OperationCode.Conv_Ovf_U2_Un: case OperationCode.Conv_Ovf_U4: case OperationCode.Conv_Ovf_U4_Un: case OperationCode.Conv_Ovf_U8: case OperationCode.Conv_Ovf_U8_Un: case OperationCode.Conv_R_Un: case OperationCode.Conv_R4: case OperationCode.Conv_R8: case OperationCode.Conv_U: case OperationCode.Conv_U1: case OperationCode.Conv_U2: case OperationCode.Conv_U4: case OperationCode.Conv_U8: case OperationCode.Isinst: case OperationCode.Ldind_I: case OperationCode.Ldind_I1: case OperationCode.Ldind_I2: case OperationCode.Ldind_I4: case OperationCode.Ldind_I8: case OperationCode.Ldind_R4: case OperationCode.Ldind_R8: case OperationCode.Ldind_Ref: case OperationCode.Ldind_U1: case OperationCode.Ldind_U2: case OperationCode.Ldind_U4: case OperationCode.Ldobj: case OperationCode.Ldflda: case OperationCode.Ldfld: case OperationCode.Ldlen: case OperationCode.Ldvirtftn: case OperationCode.Localloc: case OperationCode.Mkrefany: case OperationCode.Neg: case OperationCode.Not: case OperationCode.Refanytype: case OperationCode.Refanyval: case OperationCode.Unbox: case OperationCode.Unbox_Any: instruction.Operand1 = this.stack.Pop(); this.stack.Push(instruction); break; case OperationCode.Brfalse: case OperationCode.Brfalse_S: case OperationCode.Brtrue: case OperationCode.Brtrue_S: instruction.Operand1 = this.stack.Pop(); break; case OperationCode.Call: case OperationCode.Callvirt: var signature = instruction.Operation.Value as ISignature; Contract.Assume(signature != null); //This is an informally specified property of the Metadata model. InitializeArgumentsAndPushReturnResult(instruction, this.stack, signature); break; case OperationCode.Calli: var funcPointer = instruction.Operation.Value as IFunctionPointerTypeReference; Contract.Assume(funcPointer != null); //This is an informally specified property of the Metadata model. InitializeArgumentsAndPushReturnResult(instruction, this.stack, funcPointer); break; case OperationCode.Cpobj: case OperationCode.Stfld: case OperationCode.Stind_I: case OperationCode.Stind_I1: case OperationCode.Stind_I2: case OperationCode.Stind_I4: case OperationCode.Stind_I8: case OperationCode.Stind_R4: case OperationCode.Stind_R8: case OperationCode.Stind_Ref: case OperationCode.Stobj: instruction.Operand2 = this.stack.Pop(); instruction.Operand1 = this.stack.Pop(); break; case OperationCode.Cpblk: case OperationCode.Initblk: case OperationCode.Stelem: case OperationCode.Stelem_I: case OperationCode.Stelem_I1: case OperationCode.Stelem_I2: case OperationCode.Stelem_I4: case OperationCode.Stelem_I8: case OperationCode.Stelem_R4: case OperationCode.Stelem_R8: case OperationCode.Stelem_Ref: var indexAndValue = new Instruction[2]; indexAndValue[1] = this.stack.Pop(); indexAndValue[0] = this.stack.Pop(); instruction.Operand2 = indexAndValue; instruction.Operand1 = this.stack.Pop(); break; case OperationCode.Dup: var dupop = this.stack.Pop(); instruction.Operand1 = dupop; this.stack.Push(instruction); this.stack.Push(instruction); break; case OperationCode.Endfilter: case OperationCode.Initobj: case OperationCode.Pop: case OperationCode.Starg: case OperationCode.Starg_S: case OperationCode.Stloc: case OperationCode.Stloc_0: case OperationCode.Stloc_1: case OperationCode.Stloc_2: case OperationCode.Stloc_3: case OperationCode.Stloc_S: case OperationCode.Stsfld: case OperationCode.Throw: case OperationCode.Switch: instruction.Operand1 = this.stack.Pop(); break; case OperationCode.Leave: case OperationCode.Leave_S: this.stack.Clear(); break; case OperationCode.Newobj: Contract.Assume(instruction.Operation.Value is ISignature); //This is an informally specified property of the Metadata model. signature = (ISignature)instruction.Operation.Value; var numArguments = (int)IteratorHelper.EnumerableCount(signature.Parameters); if (numArguments > 0) { if (numArguments > 1) { numArguments--; var arguments = new Instruction[numArguments]; instruction.Operand2 = arguments; for (var i = numArguments - 1; i >= 0; i--) { arguments[i] = stack.Pop(); } } instruction.Operand1 = stack.Pop(); } this.stack.Push(instruction); break; case OperationCode.Ret: if (this.codeIsUnreachable && this.stack.Top < 0) { break; } if (this.cdfg.MethodBody.MethodDefinition.Type.TypeCode != PrimitiveTypeCode.Void) { instruction.Operand1 = this.stack.Pop(); } break; } }
private void InferTypeAndUpdateStack(Instruction instruction) { Contract.Requires(instruction != null); switch (instruction.Operation.OperationCode) { case OperationCode.Add: case OperationCode.Add_Ovf: case OperationCode.Div: case OperationCode.Mul: case OperationCode.Mul_Ovf: case OperationCode.Rem: case OperationCode.Sub: case OperationCode.Sub_Ovf: this.stack.Pop(); this.stack.Pop(); instruction.Type = this.GetBinaryNumericOperationType(instruction); this.stack.Push(instruction); break; case OperationCode.And: case OperationCode.Or: case OperationCode.Xor: Contract.Assume(instruction.Operand1 != null); Contract.Assume(instruction.Operand2 is Instruction); if (instruction.Operand1.Type.TypeCode == PrimitiveTypeCode.Boolean && ((Instruction)instruction.Operand2).Type.TypeCode == PrimitiveTypeCode.Boolean) { this.stack.Pop(); this.stack.Pop(); instruction.Type = this.platformType.SystemBoolean; this.stack.Push(instruction); break; } goto case OperationCode.Add; case OperationCode.Add_Ovf_Un: case OperationCode.Div_Un: case OperationCode.Mul_Ovf_Un: case OperationCode.Rem_Un: case OperationCode.Sub_Ovf_Un: this.stack.Pop(); this.stack.Pop(); instruction.Type = this.GetUnsignedBinaryNumericOperationType(instruction); this.stack.Push(instruction); break; case OperationCode.Arglist: instruction.Type = this.platformType.SystemRuntimeArgumentHandle; this.stack.Push(instruction); break; case OperationCode.Array_Addr: var arrayType = instruction.Operation.Value as IArrayTypeReference; Contract.Assume(arrayType != null); //This is an informally specified property of the Metadata model. for (var i = arrayType.Rank; i > 0; i--) { this.stack.Pop(); } this.stack.Pop(); instruction.Type = ManagedPointerType.GetManagedPointerType(arrayType.ElementType, this.internFactory); this.stack.Push(instruction); break; case OperationCode.Array_Create: arrayType = instruction.Operation.Value as IArrayTypeReference; Contract.Assume(arrayType != null); //This is an informally specified property of the Metadata model. for (var i = arrayType.Rank; i > 0; i--) { this.stack.Pop(); } instruction.Type = arrayType; this.stack.Push(instruction); break; case OperationCode.Array_Create_WithLowerBound: arrayType = instruction.Operation.Value as IArrayTypeReference; Contract.Assume(arrayType != null); //This is an informally specified property of the Metadata model. for (var i = arrayType.Rank * 2; i > 0; i--) { this.stack.Pop(); } instruction.Type = arrayType; this.stack.Push(instruction); break; case OperationCode.Array_Get: arrayType = instruction.Operation.Value as IArrayTypeReference; Contract.Assume(arrayType != null); //This is an informally specified property of the Metadata model. for (var i = arrayType.Rank; i > 0; i--) { this.stack.Pop(); } this.stack.Pop(); instruction.Type = arrayType.ElementType; this.stack.Push(instruction); break; case OperationCode.Array_Set: arrayType = instruction.Operation.Value as IArrayTypeReference; Contract.Assume(arrayType != null); //This is an informally specified property of the Metadata model. this.stack.Pop(); //The value to set for (var i = arrayType.Rank; i > 0; i--) { this.stack.Pop(); } this.stack.Pop(); instruction.Type = this.platformType.SystemVoid; break; case OperationCode.Beq: case OperationCode.Beq_S: case OperationCode.Bge: case OperationCode.Bge_S: case OperationCode.Bge_Un: case OperationCode.Bge_Un_S: case OperationCode.Bgt: case OperationCode.Bgt_S: case OperationCode.Bgt_Un: case OperationCode.Bgt_Un_S: case OperationCode.Ble: case OperationCode.Ble_S: case OperationCode.Ble_Un: case OperationCode.Ble_Un_S: case OperationCode.Blt: case OperationCode.Blt_S: case OperationCode.Blt_Un: case OperationCode.Blt_Un_S: case OperationCode.Bne_Un: case OperationCode.Bne_Un_S: case OperationCode.Cpobj: case OperationCode.Stfld: case OperationCode.Stind_I: case OperationCode.Stind_I1: case OperationCode.Stind_I2: case OperationCode.Stind_I4: case OperationCode.Stind_I8: case OperationCode.Stind_R4: case OperationCode.Stind_R8: case OperationCode.Stind_Ref: case OperationCode.Stobj: this.stack.Pop(); this.stack.Pop(); instruction.Type = this.platformType.SystemVoid; break; case OperationCode.Box: this.stack.Pop(); instruction.Type = this.platformType.SystemObject; this.stack.Push(instruction); break; case OperationCode.Brfalse: case OperationCode.Brfalse_S: case OperationCode.Brtrue: case OperationCode.Brtrue_S: case OperationCode.Endfilter: case OperationCode.Initobj: case OperationCode.Pop: case OperationCode.Starg: case OperationCode.Starg_S: case OperationCode.Stloc: case OperationCode.Stloc_0: case OperationCode.Stloc_1: case OperationCode.Stloc_2: case OperationCode.Stloc_3: case OperationCode.Stloc_S: case OperationCode.Stsfld: case OperationCode.Throw: case OperationCode.Switch: this.stack.Pop(); instruction.Type = this.platformType.SystemVoid; break; case OperationCode.Call: case OperationCode.Callvirt: var signature = instruction.Operation.Value as ISignature; Contract.Assume(signature != null); //This is an informally specified property of the Metadata model. var numArguments = IteratorHelper.EnumerableCount(signature.Parameters); for (var i = numArguments; i > 0; i--) { this.stack.Pop(); } if (!signature.IsStatic) { this.stack.Pop(); } instruction.Type = signature.Type; if (signature.Type.TypeCode != PrimitiveTypeCode.Void) { this.stack.Push(instruction); } break; case OperationCode.Calli: var funcPointer = instruction.Operation.Value as IFunctionPointerTypeReference; Contract.Assume(funcPointer != null); //This is an informally specified property of the Metadata model. this.stack.Pop(); //The function pointer numArguments = IteratorHelper.EnumerableCount(funcPointer.Parameters); for (var i = numArguments; i > 0; i--) { this.stack.Pop(); } if (!funcPointer.IsStatic) { this.stack.Pop(); } instruction.Type = funcPointer.Type; if (funcPointer.Type.TypeCode != PrimitiveTypeCode.Void) { this.stack.Push(instruction); } break; case OperationCode.Castclass: case OperationCode.Isinst: this.stack.Pop(); Contract.Assume(instruction.Operation.Value is ITypeReference); //This is an informally specified property of the Metadata model. instruction.Type = (ITypeReference)instruction.Operation.Value; this.stack.Push(instruction); break; case OperationCode.Ceq: case OperationCode.Cgt: case OperationCode.Cgt_Un: case OperationCode.Clt: case OperationCode.Clt_Un: this.stack.Pop(); this.stack.Pop(); instruction.Type = this.platformType.SystemBoolean; this.stack.Push(instruction); break; case OperationCode.Ckfinite: case OperationCode.Neg: case OperationCode.Not: this.stack.Pop(); Contract.Assume(instruction.Operand1 != null); //Assumed because of the informal specification of the DataFlowInferencer instruction.Type = instruction.Operand1.Type; this.stack.Push(instruction); break; case OperationCode.Conv_I: case OperationCode.Conv_Ovf_I: case OperationCode.Conv_Ovf_I_Un: case OperationCode.Ldind_I: case OperationCode.Localloc: this.stack.Pop(); instruction.Type = this.platformType.SystemIntPtr; this.stack.Push(instruction); break; case OperationCode.Conv_I1: case OperationCode.Conv_Ovf_I1: case OperationCode.Conv_Ovf_I1_Un: case OperationCode.Ldind_I1: this.stack.Pop(); instruction.Type = this.platformType.SystemInt8; this.stack.Push(instruction); break; case OperationCode.Conv_I2: case OperationCode.Conv_Ovf_I2: case OperationCode.Conv_Ovf_I2_Un: case OperationCode.Ldind_I2: this.stack.Pop(); instruction.Type = this.platformType.SystemInt16; this.stack.Push(instruction); break; case OperationCode.Conv_I4: case OperationCode.Conv_Ovf_I4: case OperationCode.Conv_Ovf_I4_Un: case OperationCode.Ldind_I4: this.stack.Pop(); instruction.Type = this.platformType.SystemInt32; this.stack.Push(instruction); break; case OperationCode.Conv_I8: case OperationCode.Conv_Ovf_I8: case OperationCode.Conv_Ovf_I8_Un: case OperationCode.Ldind_I8: this.stack.Pop(); instruction.Type = this.platformType.SystemInt64; this.stack.Push(instruction); break; case OperationCode.Conv_Ovf_U: case OperationCode.Conv_Ovf_U_Un: case OperationCode.Conv_U: case OperationCode.Ldlen: this.stack.Pop(); instruction.Type = this.platformType.SystemUIntPtr; this.stack.Push(instruction); break; case OperationCode.Conv_Ovf_U1: case OperationCode.Conv_Ovf_U1_Un: case OperationCode.Conv_U1: case OperationCode.Ldind_U1: this.stack.Pop(); instruction.Type = this.platformType.SystemUInt8; this.stack.Push(instruction); break; case OperationCode.Conv_Ovf_U2: case OperationCode.Conv_Ovf_U2_Un: case OperationCode.Conv_U2: case OperationCode.Ldind_U2: this.stack.Pop(); instruction.Type = this.platformType.SystemUInt16; this.stack.Push(instruction); break; case OperationCode.Conv_Ovf_U4: case OperationCode.Conv_Ovf_U4_Un: case OperationCode.Conv_U4: case OperationCode.Ldind_U4: this.stack.Pop(); instruction.Type = this.platformType.SystemUInt32; this.stack.Push(instruction); break; case OperationCode.Conv_Ovf_U8: case OperationCode.Conv_Ovf_U8_Un: case OperationCode.Conv_U8: this.stack.Pop(); instruction.Type = this.platformType.SystemUInt64; this.stack.Push(instruction); break; case OperationCode.Conv_R_Un: this.stack.Pop(); Contract.Assume(instruction.Operand1 != null); //Assumed because of the informal specification of the DataFlowInferencer if (TypeHelper.SizeOfType(instruction.Operand1.Type) < 4) { instruction.Type = this.platformType.SystemFloat32; } else { instruction.Type = this.platformType.SystemFloat64; } this.stack.Push(instruction); break; case OperationCode.Conv_R4: case OperationCode.Ldind_R4: this.stack.Pop(); instruction.Type = this.platformType.SystemFloat32; this.stack.Push(instruction); break; case OperationCode.Conv_R8: case OperationCode.Ldind_R8: this.stack.Pop(); instruction.Type = this.platformType.SystemFloat64; this.stack.Push(instruction); break; case OperationCode.Cpblk: case OperationCode.Initblk: case OperationCode.Stelem: case OperationCode.Stelem_I: case OperationCode.Stelem_I1: case OperationCode.Stelem_I2: case OperationCode.Stelem_I4: case OperationCode.Stelem_I8: case OperationCode.Stelem_R4: case OperationCode.Stelem_R8: case OperationCode.Stelem_Ref: this.stack.Pop(); this.stack.Pop(); this.stack.Pop(); instruction.Type = this.platformType.SystemVoid; break; case OperationCode.Dup: Contract.Assume(instruction.Operand1 != null); //Assumed because of the informal specification of the DataFlowInferencer instruction.Type = instruction.Operand1.Type; this.stack.Push(instruction); break; case OperationCode.Ldarg: case OperationCode.Ldarg_0: case OperationCode.Ldarg_1: case OperationCode.Ldarg_2: case OperationCode.Ldarg_3: case OperationCode.Ldarg_S: var parameter = instruction.Operation.Value as IParameterDefinition; if (parameter == null) //this arg { instruction.Type = this.cfg.MethodBody.MethodDefinition.ContainingType; if (instruction.Type.IsValueType) { instruction.Type = ManagedPointerType.GetManagedPointerType(instruction.Type, this.internFactory); } } else { instruction.Type = parameter.Type; if (parameter.IsByReference) { instruction.Type = ManagedPointerType.GetManagedPointerType(instruction.Type, this.internFactory); } } this.stack.Push(instruction); break; case OperationCode.Ldarga: case OperationCode.Ldarga_S: parameter = instruction.Operation.Value as IParameterDefinition; if (parameter == null) //this arg { instruction.Type = ManagedPointerType.GetManagedPointerType(this.cfg.MethodBody.MethodDefinition.ContainingType, this.internFactory); } else { instruction.Type = ManagedPointerType.GetManagedPointerType(parameter.Type, this.internFactory); if (parameter.IsByReference) { instruction.Type = ManagedPointerType.GetManagedPointerType(instruction.Type, this.internFactory); } } this.stack.Push(instruction); break; case OperationCode.Ldc_I4: case OperationCode.Ldc_I4_0: case OperationCode.Ldc_I4_1: case OperationCode.Ldc_I4_2: case OperationCode.Ldc_I4_3: case OperationCode.Ldc_I4_4: case OperationCode.Ldc_I4_5: case OperationCode.Ldc_I4_6: case OperationCode.Ldc_I4_7: case OperationCode.Ldc_I4_8: case OperationCode.Ldc_I4_M1: case OperationCode.Ldc_I4_S: instruction.Type = this.platformType.SystemInt32; this.stack.Push(instruction); break; case OperationCode.Ldc_I8: instruction.Type = this.platformType.SystemInt64; this.stack.Push(instruction); break; case OperationCode.Ldc_R4: instruction.Type = this.platformType.SystemFloat32; this.stack.Push(instruction); break; case OperationCode.Ldc_R8: instruction.Type = this.platformType.SystemFloat64; this.stack.Push(instruction); break; case OperationCode.Ldelem: this.stack.Pop(); this.stack.Pop(); Contract.Assume(instruction.Operation.Value is ITypeReference); //This is an informally specified property of the Metadata model. instruction.Type = (ITypeReference)instruction.Operation.Value; this.stack.Push(instruction); break; case OperationCode.Ldobj: case OperationCode.Unbox_Any: this.stack.Pop(); Contract.Assume(instruction.Operation.Value is ITypeReference); //This is an informally specified property of the Metadata model. instruction.Type = (ITypeReference)instruction.Operation.Value; this.stack.Push(instruction); break; case OperationCode.Ldelem_I: this.stack.Pop(); this.stack.Pop(); instruction.Type = this.platformType.SystemIntPtr; this.stack.Push(instruction); break; case OperationCode.Ldelem_I1: this.stack.Pop(); this.stack.Pop(); instruction.Type = this.platformType.SystemInt8; this.stack.Push(instruction); break; case OperationCode.Ldelem_I2: this.stack.Pop(); this.stack.Pop(); instruction.Type = this.platformType.SystemInt16; this.stack.Push(instruction); break; case OperationCode.Ldelem_I4: this.stack.Pop(); this.stack.Pop(); instruction.Type = this.platformType.SystemInt32; this.stack.Push(instruction); break; case OperationCode.Ldelem_I8: this.stack.Pop(); this.stack.Pop(); instruction.Type = this.platformType.SystemInt64; this.stack.Push(instruction); break; case OperationCode.Ldelem_Ref: this.stack.Pop(); this.stack.Pop(); Contract.Assume(instruction.Operand1 != null); //Assumed because of the informal specification of the DataFlowInferencer arrayType = instruction.Operand1.Type as IArrayTypeReference; if (arrayType != null) { instruction.Type = arrayType.ElementType; } else //Should only get here if the IL is bad. { instruction.Type = this.platformType.SystemObject; } this.stack.Push(instruction); break; case OperationCode.Ldelem_R4: this.stack.Pop(); this.stack.Pop(); instruction.Type = this.platformType.SystemFloat32; this.stack.Push(instruction); break; case OperationCode.Ldelem_R8: this.stack.Pop(); this.stack.Pop(); instruction.Type = this.platformType.SystemFloat64; this.stack.Push(instruction); break; case OperationCode.Ldelem_U1: this.stack.Pop(); this.stack.Pop(); instruction.Type = this.platformType.SystemUInt8; this.stack.Push(instruction); break; case OperationCode.Ldelem_U2: this.stack.Pop(); this.stack.Pop(); instruction.Type = this.platformType.SystemUInt16; this.stack.Push(instruction); break; case OperationCode.Ldelem_U4: this.stack.Pop(); this.stack.Pop(); instruction.Type = this.platformType.SystemUInt32; this.stack.Push(instruction); break; case OperationCode.Ldelema: this.stack.Pop(); this.stack.Pop(); Contract.Assume(instruction.Operation.Value is ITypeReference); //This is an informally specified property of the Metadata model. instruction.Type = ManagedPointerType.GetManagedPointerType((ITypeReference)instruction.Operation.Value, this.internFactory); this.stack.Push(instruction); break; case OperationCode.Ldfld: this.stack.Pop(); Contract.Assume(instruction.Operation.Value is IFieldReference); //This is an informally specified property of the Metadata model. instruction.Type = ((IFieldReference)instruction.Operation.Value).Type; this.stack.Push(instruction); break; case OperationCode.Ldsfld: Contract.Assume(instruction.Operation.Value is IFieldReference); //This is an informally specified property of the Metadata model. instruction.Type = ((IFieldReference)instruction.Operation.Value).Type; this.stack.Push(instruction); break; case OperationCode.Ldflda: this.stack.Pop(); Contract.Assume(instruction.Operation.Value is IFieldReference); //This is an informally specified property of the Metadata model. instruction.Type = ManagedPointerType.GetManagedPointerType(((IFieldReference)instruction.Operation.Value).Type, this.internFactory); this.stack.Push(instruction); break; case OperationCode.Ldsflda: Contract.Assume(instruction.Operation.Value is IFieldReference); //This is an informally specified property of the Metadata model. instruction.Type = ManagedPointerType.GetManagedPointerType(((IFieldReference)instruction.Operation.Value).Type, this.internFactory); this.stack.Push(instruction); break; case OperationCode.Ldftn: Contract.Assume(instruction.Operation.Value is IMethodReference); //This is an informally specified property of the Metadata model. instruction.Type = new FunctionPointerType((IMethodReference)instruction.Operation.Value, this.internFactory); this.stack.Push(instruction); break; case OperationCode.Ldvirtftn: this.stack.Pop(); Contract.Assume(instruction.Operation.Value is IMethodReference); //This is an informally specified property of the Metadata model. instruction.Type = new FunctionPointerType((IMethodReference)instruction.Operation.Value, this.internFactory); this.stack.Push(instruction); break; case OperationCode.Ldind_Ref: this.stack.Pop(); Contract.Assume(instruction.Operand1 != null); //Assumed because of the informal specification of the DataFlowInferencer var ptr = instruction.Operand1.Type as IPointerTypeReference; if (ptr != null) { instruction.Type = ptr.TargetType; } else { Contract.Assume(instruction.Operand1.Type is IManagedPointerTypeReference); //This is an informally specified property of the Metadata model. instruction.Type = ((IManagedPointerTypeReference)instruction.Operand1.Type).TargetType; } this.stack.Push(instruction); break; case OperationCode.Ldloc: case OperationCode.Ldloc_0: case OperationCode.Ldloc_1: case OperationCode.Ldloc_2: case OperationCode.Ldloc_3: case OperationCode.Ldloc_S: var local = instruction.Operation.Value as ILocalDefinition; Contract.Assume(local != null); //This is an informally specified property of the Metadata model. instruction.Type = local.Type; if (local.IsReference) { instruction.Type = ManagedPointerType.GetManagedPointerType(instruction.Type, this.internFactory); } this.stack.Push(instruction); break; case OperationCode.Ldloca: case OperationCode.Ldloca_S: local = instruction.Operation.Value as ILocalDefinition; Contract.Assume(local != null); //This is an informally specified property of the Metadata model. instruction.Type = ManagedPointerType.GetManagedPointerType(local.Type, this.internFactory); if (local.IsReference) { instruction.Type = ManagedPointerType.GetManagedPointerType(instruction.Type, this.internFactory); } this.stack.Push(instruction); break; case OperationCode.Ldnull: instruction.Type = this.platformType.SystemObject; this.stack.Push(instruction); break; case OperationCode.Ldstr: instruction.Type = this.platformType.SystemString; this.stack.Push(instruction); break; case OperationCode.Ldtoken: if (instruction.Operation.Value is IMethodReference) { instruction.Type = this.platformType.SystemRuntimeMethodHandle; } else if (instruction.Operation.Value is ITypeReference) { instruction.Type = this.platformType.SystemRuntimeTypeHandle; } else if (instruction.Operation.Value is IFieldReference) { instruction.Type = this.platformType.SystemRuntimeFieldHandle; } else { //this should never happen in well formed IL. instruction.Type = this.platformType.SystemVoid; } this.stack.Push(instruction); break; case OperationCode.Leave: case OperationCode.Leave_S: this.stack.Clear(); break; case OperationCode.Mkrefany: this.stack.Pop(); instruction.Type = this.platformType.SystemTypedReference; this.stack.Push(instruction); break; case OperationCode.Newarr: this.stack.Pop(); Contract.Assume(instruction.Operation.Value is ITypeReference); //This is an informally specified property of the Metadata model. instruction.Type = (ITypeReference)instruction.Operation.Value; this.stack.Push(instruction); break; case OperationCode.Newobj: var constructorReference = instruction.Operation.Value as IMethodReference; Contract.Assume(constructorReference != null); //This is an informally specified property of the Metadata model. for (var i = constructorReference.ParameterCount; i > 0; i--) { this.stack.Pop(); } instruction.Type = constructorReference.ContainingType; this.stack.Push(instruction); break; case OperationCode.Refanytype: this.stack.Pop(); instruction.Type = this.platformType.SystemRuntimeTypeHandle; this.stack.Push(instruction); break; case OperationCode.Refanyval: this.stack.Pop(); Contract.Assume(instruction.Operation.Value is ITypeReference); //This is an informally specified property of the Metadata model. instruction.Type = ManagedPointerType.GetManagedPointerType((ITypeReference)instruction.Operation.Value, this.internFactory); this.stack.Push(instruction); break; case OperationCode.Ret: if (this.cfg.MethodBody.MethodDefinition.Type.TypeCode != PrimitiveTypeCode.Void) { instruction.Operand1 = this.stack.Pop(); } instruction.Type = this.platformType.SystemVoid; break; case OperationCode.Shl: case OperationCode.Shr: case OperationCode.Shr_Un: this.stack.Pop(); this.stack.Pop(); Contract.Assume(instruction.Operand1 != null); //Assumed because of the informal specification of the DataFlowInferencer instruction.Type = instruction.Operand1.Type; this.stack.Push(instruction); break; case OperationCode.Sizeof: instruction.Type = this.platformType.SystemUInt32; this.stack.Push(instruction); break; case OperationCode.Unbox: this.stack.Pop(); Contract.Assume(instruction.Operation.Value is ITypeReference); //This is an informally specified property of the Metadata model. instruction.Type = ManagedPointerType.GetManagedPointerType((ITypeReference)instruction.Operation.Value, this.internFactory); this.stack.Push(instruction); break; default: instruction.Type = this.platformType.SystemVoid; break; } }
private IMethodReference GetCorrespondingThreeArgContractMethod(IMethodReference originalMethod) { ushort genericParameters = 0; string contractMethodName = originalMethod.Name.Value; string keyName = contractMethodName; IGenericMethodInstanceReference methodInstance = originalMethod as IGenericMethodInstanceReference; if (methodInstance != null) { originalMethod = methodInstance.GenericMethod; genericParameters = originalMethod.GenericParameterCount; keyName = originalMethod.Name.Value + genericParameters; } #region Backward compatibility with v4 Beta 1 which went out with RequiresAlways in it (REMOVE WHEN THAT IS DELETED) bool backwardCompat = false; if (contractMethodName.Equals("RequiresAlways")) { contractMethodName = "Requires1"; // The one is for the generic parameter genericParameters = 1; backwardCompat = true; } #endregion Backward compatibility with v4 Beta 1 which went out with RequiresAlways in it (REMOVE WHEN THAT IS DELETED) IMethodReference methodToUse; this.threeArgumentVersionofContractMethod.TryGetValue(keyName, out methodToUse); if (methodToUse == null) { #region Create a method methodToUse = CreateThreeArgVersionOfMethod(contractMethodName, keyName, genericParameters, backwardCompat); #endregion Create a method } if (genericParameters != 0) { // instantiate method to use methodToUse = new Microsoft.Cci.Immutable.GenericMethodInstanceReference(methodToUse, backwardCompat ? IteratorHelper.GetSingletonEnumerable <ITypeReference>(this.systemArgumentExceptionType) : methodInstance.GenericArguments, this.host.InternFactory); var key = methodToUse.InternedKey; } return(methodToUse); }
public override IStatement Rewrite(IForEachStatement forEachStatement) { ILocalDefinition foreachLocal; var key = forEachStatement.Collection.Type.InternedKey; ITypeReference enumeratorType; IMethodReference getEnumerator; IMethodReference getCurrent; var gtir = forEachStatement.Collection.Type as IGenericTypeInstanceReference; if (gtir != null) { var typeArguments = gtir.GenericArguments; ITypeReference genericEnumeratorType = new Immutable.GenericTypeInstanceReference(this.host.PlatformType.SystemCollectionsGenericIEnumerator, typeArguments, this.host.InternFactory); ITypeReference genericEnumerableType = new Immutable.GenericTypeInstanceReference(this.host.PlatformType.SystemCollectionsGenericIEnumerable, typeArguments, this.host.InternFactory); enumeratorType = genericEnumeratorType; getEnumerator = new SpecializedMethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = genericEnumerableType, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor("GetEnumerator"), Parameters = new List <IParameterTypeInformation>(), Type = genericEnumeratorType, UnspecializedVersion = new MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = this.host.PlatformType.SystemCollectionsGenericIEnumerable, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor("GetEnumerator"), Parameters = new List <IParameterTypeInformation>(), Type = this.host.PlatformType.SystemCollectionsGenericIEnumerator, }, }; var getEnumerator2 = (IMethodReference) IteratorHelper.First(genericEnumerableType.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("GetEnumerator"), false)); getEnumerator = getEnumerator2; getCurrent = (IMethodReference)IteratorHelper.First(genericEnumeratorType.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("get_Current"), false)); } else { enumeratorType = this.host.PlatformType.SystemCollectionsIEnumerator; getEnumerator = new MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = enumeratorType, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor("GetEnumerator"), Parameters = new List <IParameterTypeInformation>(), Type = this.host.PlatformType.SystemCollectionsIEnumerable, }; getCurrent = new MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = enumeratorType, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor("get_Current"), Parameters = new List <IParameterTypeInformation>(), Type = this.host.PlatformType.SystemObject, }; } var initializer = new MethodCall() { Arguments = new List <IExpression>(), IsStaticCall = false, IsVirtualCall = true, MethodToCall = getEnumerator, ThisArgument = forEachStatement.Collection, Type = enumeratorType, }; IStatement initialization; if (!this.foreachLocals.TryGetValue(key, out foreachLocal)) { foreachLocal = new LocalDefinition() { Type = enumeratorType, Name = this.host.NameTable.GetNameFor("CS$5$" + this.foreachLocals.Count) }; this.foreachLocals.Add(key, foreachLocal); initialization = new LocalDeclarationStatement() { InitialValue = initializer, LocalVariable = foreachLocal, }; } else { initialization = new ExpressionStatement() { Expression = new Assignment() { Source = initializer, Target = new TargetExpression() { Definition = foreachLocal, Instance = null, Type = foreachLocal.Type, }, Type = foreachLocal.Type, }, }; } var newStmts = new List <IStatement>(); newStmts.Add(new ExpressionStatement() { Expression = new Assignment() { Source = new MethodCall() { Arguments = new List <IExpression>(), IsStaticCall = false, IsVirtualCall = true, MethodToCall = getCurrent, ThisArgument = new BoundExpression() { Definition = foreachLocal, Instance = null, }, Type = forEachStatement.Variable.Type, }, Target = new TargetExpression() { Definition = forEachStatement.Variable, Instance = null, }, Type = forEachStatement.Variable.Type, }, }); newStmts.Add(forEachStatement.Body); var newBody = new BlockStatement() { Statements = newStmts, }; var result = new BlockStatement() { Statements = new List <IStatement>() { initialization, new TryCatchFinallyStatement() { TryBody = new BlockStatement() { Statements = new List <IStatement>() { new WhileDoStatement() { Body = newBody, Condition = new MethodCall() { Arguments = new List <IExpression>(), IsStaticCall = false, IsVirtualCall = true, MethodToCall = moveNext, ThisArgument = new BoundExpression() { Definition = foreachLocal, Instance = null, }, Type = this.host.PlatformType.SystemBoolean, }, }, }, }, FinallyBody = new BlockStatement() { Statements = new List <IStatement>() { new ConditionalStatement() { Condition = new Equality() { LeftOperand = new BoundExpression() { Definition = foreachLocal, Instance = null, Type = foreachLocal.Type, }, RightOperand = new CompileTimeConstant() { Type = foreachLocal.Type, Value = null, }, Type = this.host.PlatformType.SystemBoolean, }, FalseBranch = new EmptyStatement(), TrueBranch = new ExpressionStatement() { Expression = new MethodCall() { Arguments = new List <IExpression>(), IsStaticCall = false, IsVirtualCall = true, MethodToCall = this.disposeMethod, ThisArgument = new BoundExpression() { Definition = foreachLocal, Instance = null, }, Type = this.host.PlatformType.SystemVoid, }, }, }, }, }, }, }, }; return(result); }
public override AssemblyIdentity UnifyAssembly(AssemblyIdentity assemblyIdentity) { Dictionary <String, Byte[]> assembliesToUnify = new Dictionary <string, Byte[]> { { "System", new Byte[] { 0xb7, 0x7a, 0x5c, 0x56, 0x19, 0x34, 0xe0, 0x89 } }, { "System.Drawing", new Byte[] { 0xb0, 0x3f, 0x5f, 0x7f, 0x11, 0xd5, 0x0a, 0x3a } }, { "System.Windows.Forms", new Byte[] { 0xb7, 0x7a, 0x5c, 0x56, 0x19, 0x34, 0xe0, 0x89 } }, }; Byte[] publicKeyToken; if (assembliesToUnify.TryGetValue(assemblyIdentity.Name.Value, out publicKeyToken) && IteratorHelper.EnumerablesAreEqual <Byte>(publicKeyToken, assemblyIdentity.PublicKeyToken)) { assemblyIdentity = new AssemblyIdentity( assemblyIdentity.Name, assemblyIdentity.Culture, CoreAssemblySymbolicIdentity.Version, // roll forward to the version of mscorlib assemblyIdentity.PublicKeyToken, assemblyIdentity.Location); } return(base.UnifyAssembly(assemblyIdentity)); }