/// <summary> /// Get the reference of a method in the closure class as used by other methods in the same class. /// </summary> private IMethodReference GetReferenceOfMethodUsedByPeers(IMethodDefinition method) { IMethodReference methodReference = null; ITypeReference typeReference = this.ClosureDefinitionReference; ISpecializedNestedTypeReference specializedNestedTypeRef = typeReference as ISpecializedNestedTypeReference; IGenericTypeInstanceReference genericInstanceRef = typeReference as IGenericTypeInstanceReference; if (specializedNestedTypeRef != null || genericInstanceRef != null) { methodReference = new SpecializedMethodReference() { ContainingType = typeReference, GenericParameterCount = method.GenericParameterCount, InternFactory = this.host.InternFactory, UnspecializedVersion = method, Type = method.Type, Name = method.Name, CallingConvention = method.CallingConvention, Parameters = method.ParameterCount == 0 ? null : new List <IParameterTypeInformation>(((IMethodReference)method).Parameters), ExtraParameters = null, ReturnValueIsByRef = method.ReturnValueIsByRef, ReturnValueIsModified = method.ReturnValueIsModified, Attributes = null, }; } else { methodReference = method; } return(methodReference); }
internal Microsoft.Cci.IMethodReference Translate(MethodSymbol methodSymbol, bool needDeclaration) { object reference; Microsoft.Cci.IMethodReference methodRef; NamedTypeSymbol container = methodSymbol.ContainingType; System.Diagnostics.Debug.Assert(ReferenceEquals(methodSymbol, methodSymbol.OriginalDefinition) || !methodSymbol.Equals(methodSymbol.OriginalDefinition)); if (!ReferenceEquals(methodSymbol.OriginalDefinition, methodSymbol)) { System.Diagnostics.Debug.Assert(!needDeclaration); return(methodSymbol); } else if (!needDeclaration) { bool methodIsGeneric = methodSymbol.IsGeneric; bool typeIsGeneric = IsGenericType(container); if (methodIsGeneric || typeIsGeneric) { if (genericInstanceMap.TryGetValue(methodSymbol, out reference)) { return((Microsoft.Cci.IMethodReference)reference); } if (methodIsGeneric) { if (typeIsGeneric) { // Specialized and generic instance at the same time. throw new NotImplementedException(); } else { methodRef = new GenericMethodInstanceReference(methodSymbol); } } else { System.Diagnostics.Debug.Assert(typeIsGeneric); methodRef = new SpecializedMethodReference(methodSymbol); } genericInstanceMap.Add(methodSymbol, methodRef); return(methodRef); } } return(methodSymbol); }
//^ invariant this.PEFileReader.MethodSpecTable.NumberOfRows >= 1 ==> this.MethodSpecHashtable != null; internal ITypeMemberReference/*?*/ GetModuleMemberReferenceAtRowWorker( MetadataObject owningObject, uint memberRefRowId ) { if (memberRefRowId == 0 || memberRefRowId > this.PEFileReader.MemberRefTable.NumberOfRows) { return null; } if (this.ModuleMemberReferenceArray[memberRefRowId] == null) { MemberRefRow memberRefRow = this.PEFileReader.MemberRefTable[memberRefRowId]; uint classTokenType = memberRefRow.Class & TokenTypeIds.TokenTypeMask; uint classRowId = memberRefRow.Class & TokenTypeIds.RIDMask; ITypeReference/*?*/ parentTypeReference = null; switch (classTokenType) { case TokenTypeIds.TypeDef: parentTypeReference = this.GetTypeDefinitionAtRow(classRowId); break; case TokenTypeIds.TypeRef: parentTypeReference = this.GetTypeRefReferenceAtRow(classRowId); break; case TokenTypeIds.TypeSpec: parentTypeReference = this.GetTypeSpecReferenceAtRow(owningObject, classRowId).UnderlyingModuleTypeReference; break; case TokenTypeIds.MethodDef: { var/*?*/ methodDef = this.GetMethodDefAtRow(classRowId); if (methodDef == null) { // Error... return null; } parentTypeReference = methodDef.ContainingType; break; } case TokenTypeIds.ModuleRef: { ModuleReference/*?*/ modRef = this.GetModuleReferenceAt(classRowId); if (modRef == null) { // MDError return null; } var module = this.ResolveModuleRefReference(modRef) as Module; if (module == null) { //TODO: MDError... return null; } PEFileToObjectModel modulePEFileToObjectModel = module.PEFileToObjectModel; parentTypeReference = modulePEFileToObjectModel._Module_; break; } default: { // MDError... return null; } } if (parentTypeReference == null) { // Error... return null; } MemberReference retModuleMemberReference; IName name = this.GetNameFromOffset(memberRefRow.Name); byte firstByte = this.PEFileReader.BlobStream.GetByteAt(memberRefRow.Signature, 0); var genericTypeInstance = parentTypeReference as IGenericTypeInstanceReference; var specializedNestedTypeReference = parentTypeReference as ISpecializedNestedTypeReference; if (SignatureHeader.IsFieldSignature(firstByte)) { if (genericTypeInstance != null || specializedNestedTypeReference != null) { //The same memberRef token can be shared by distinct instance references, therefore special caching is required FieldReference unspecializedFieldReference = this.UnspecializedMemberReferenceArray[memberRefRowId] as FieldReference; if (unspecializedFieldReference == null) { unspecializedFieldReference = new FieldReference(this, memberRefRowId, TypeCache.Unspecialize(parentTypeReference), name); this.UnspecializedMemberReferenceArray[memberRefRowId] = unspecializedFieldReference; } uint key1 = parentTypeReference.InternedKey; uint key2 = unspecializedFieldReference.InternedKey; var specializedField = this.SpecializedFieldHashtable.Find(key1, key2); if (specializedField == null) { specializedField = new SpecializedFieldReference(parentTypeReference, unspecializedFieldReference, this.InternFactory); this.SpecializedFieldHashtable.Add(key1, key2, specializedField); } return specializedField; } else { retModuleMemberReference = new FieldReference(this, memberRefRowId, parentTypeReference, name); } } else if (SignatureHeader.IsMethodSignature(firstByte)) { if (genericTypeInstance != null || specializedNestedTypeReference != null) { //The same memberRef token can be shared by distinct instance references, therefore special caching is required MethodReference unspecializedMethodReference = this.UnspecializedMemberReferenceArray[memberRefRowId] as MethodReference; if (unspecializedMethodReference == null) { unspecializedMethodReference = new MethodReference(this, memberRefRowId, TypeCache.Unspecialize(parentTypeReference), name, firstByte); this.UnspecializedMemberReferenceArray[memberRefRowId] = unspecializedMethodReference; } uint key1 = parentTypeReference.InternedKey; uint key2 = unspecializedMethodReference.InternedKey; var specializedMethod = this.SpecializedMethodHashtable.Find(key1, key2); if (specializedMethod == null) { specializedMethod = new SpecializedMethodReference(parentTypeReference, unspecializedMethodReference, this.InternFactory); this.SpecializedMethodHashtable.Add(key1, key2, specializedMethod); } return specializedMethod; } else { retModuleMemberReference = new MethodReference(this, memberRefRowId, parentTypeReference, name, firstByte); } } else { // MD Error return null; } this.ModuleMemberReferenceArray[memberRefRowId] = retModuleMemberReference; } MemberReference/*?*/ ret = this.ModuleMemberReferenceArray[memberRefRowId]; return ret; }
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); }
internal Microsoft.Cci.IMethodReference Translate(MethodSymbol methodSymbol, bool needDeclaration) { object reference; Microsoft.Cci.IMethodReference methodRef; NamedTypeSymbol container = methodSymbol.ContainingType; System.Diagnostics.Debug.Assert(ReferenceEquals(methodSymbol, methodSymbol.OriginalDefinition) || !methodSymbol.Equals(methodSymbol.OriginalDefinition)); if (!ReferenceEquals(methodSymbol.OriginalDefinition, methodSymbol)) { System.Diagnostics.Debug.Assert(!needDeclaration); return methodSymbol; } else if (!needDeclaration) { bool methodIsGeneric = methodSymbol.IsGeneric; bool typeIsGeneric = IsGenericType(container); if (methodIsGeneric || typeIsGeneric) { if (genericInstanceMap.TryGetValue(methodSymbol, out reference)) { return (Microsoft.Cci.IMethodReference)reference; } if (methodIsGeneric) { if (typeIsGeneric) { // Specialized and generic instance at the same time. throw new NotImplementedException(); } else { methodRef = new GenericMethodInstanceReference(methodSymbol); } } else { System.Diagnostics.Debug.Assert(typeIsGeneric); methodRef = new SpecializedMethodReference(methodSymbol); } genericInstanceMap.Add(methodSymbol, methodRef); return methodRef; } } return methodSymbol; }
/// <summary> /// Get the reference of a method in the closure class as used by other methods in the same class. /// </summary> private IMethodReference GetReferenceOfMethodUsedByPeers(IMethodDefinition method) { IMethodReference methodReference = null; ITypeReference typeReference = this.ClosureDefinitionReference; ISpecializedNestedTypeReference specializedNestedTypeRef = typeReference as ISpecializedNestedTypeReference; IGenericTypeInstanceReference genericInstanceRef = typeReference as IGenericTypeInstanceReference; if (specializedNestedTypeRef != null || genericInstanceRef != null) { methodReference = new SpecializedMethodReference() { ContainingType = typeReference, GenericParameterCount = method.GenericParameterCount, InternFactory = this.host.InternFactory, UnspecializedVersion = method, Type = method.Type, Name = method.Name, CallingConvention = method.CallingConvention, Parameters = method.ParameterCount == 0 ? null : new List<IParameterTypeInformation>(((IMethodReference)method).Parameters), ExtraParameters = null, ReturnValueIsByRef = method.ReturnValueIsByRef, ReturnValueIsModified = method.ReturnValueIsModified, Attributes = null, }; } else methodReference = method; return methodReference; }
/// <summary /> 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; }
/// <summary> /// Instantiate a closure class method using the generic method parameters of the iterator method, if any. /// </summary> IMethodReference GetMethodReference(IteratorClosureInformation iteratorClosure, IMethodDefinition methodDefinition) { ITypeReference typeReference = GetClosureTypeReferenceFromIterator(iteratorClosure); IMethodReference methodReference = methodDefinition; ISpecializedNestedTypeReference specializedNestedTypeRef = typeReference as ISpecializedNestedTypeReference; IGenericTypeInstanceReference genericInstanceRef = typeReference as IGenericTypeInstanceReference; if (specializedNestedTypeRef != null || genericInstanceRef != null) { methodReference = new SpecializedMethodReference() { ContainingType = typeReference, GenericParameterCount = methodDefinition.GenericParameterCount, InternFactory = this.host.InternFactory, UnspecializedVersion = methodDefinition, Type = methodDefinition.Type, Name = methodDefinition.Name, CallingConvention = methodDefinition.CallingConvention, Parameters = methodDefinition.ParameterCount == 0 ? null : new List<IParameterTypeInformation>(((IMethodReference)methodDefinition).Parameters), ExtraParameters = null, ReturnValueIsByRef = methodDefinition.ReturnValueIsByRef, ReturnValueIsModified = methodDefinition.ReturnValueIsModified, Attributes = null, }; } return methodReference; }
/// <summary> /// If the method reference's containing type is the unspecialized type this /// rewriter was created for, then it returns a specialized method reference /// whose containing type is the specialized type this rewriter was created for. /// </summary> /// <param name="methodDefinition"></param> /// <returns></returns> public override IMethodDefinition Rewrite(IMethodDefinition methodDefinition) { if (this.isSpecialized && TypeHelper.TypesAreEquivalent(methodDefinition.ContainingType, this.unspec)) { var smr = new SpecializedMethodReference() { UnspecializedVersion = methodDefinition, ContainingType = this.context, CallingConvention = methodDefinition.CallingConvention, InternFactory = this.host.InternFactory, Name = methodDefinition.Name, Parameters = new List<IParameterTypeInformation>(methodDefinition.Parameters), Type = methodDefinition.Type, }; return smr.ResolvedMethod; }; return base.Rewrite(methodDefinition); }
/// <summary> /// Rewrites the given specialized method reference. /// </summary> /// <param name="specializedMethodReference"></param> public override void RewriteChildren(SpecializedMethodReference specializedMethodReference) { specializedMethodReference.ContainingType = this.Rewrite(specializedMethodReference.ContainingType); specializedMethodReference.Parameters = this.Rewrite(specializedMethodReference.Parameters); specializedMethodReference.Type = this.Rewrite(specializedMethodReference.Type); }