A metadata (IL) representation along with a source level representation of the body of a method or of a property/event accessor.
Inheritance: ISourceMethodBody
            public override IMethodBody Rewrite(IMethodBody body)
            {
                var method = body.MethodDefinition;
                _log.Info("Rewriting IMethodBody of: " + method + " Pass: " + MutationTarget.PassInfo);
     
                var newBody = new SourceMethodBody(Host)
                {
                    MethodDefinition = method,
                    LocalsAreZeroed = true
                };
                var block = new BlockStatement();
                newBody.Block = block;

                var replacement = method.ContainingTypeDefinition.Methods.Single(m => m.ToString() == MutationTarget.PassInfo);
                var methodCall = new MethodCall
                    {
                        MethodToCall = replacement,
                        Type = replacement.Type,
                        ThisArgument = new ThisReference() {Type = method.ContainingTypeDefinition}
                    };
                foreach (var param in replacement.Parameters)
                {
                    methodCall.Arguments.Add(new BoundExpression()
                        {
                            Definition = method.Parameters
                                .First(p =>
                                    ((INamedTypeReference)p.Type).Name.Value ==
                                    ((INamedTypeReference)param.Type).Name.Value)
                        });
                    //  methodCall.Arguments.Add(method.Parameters.First(p => new ));
                }

                if (replacement.Type == Host.PlatformType.SystemVoid)
                {
                    block.Statements.Add(new ExpressionStatement
                    {
                        Expression = methodCall
                    });
                    block.Statements.Add(new ReturnStatement());
                }
                else
                {
                    block.Statements.Add(new ReturnStatement
                    {
                        Expression = methodCall
                    });
                   
                }
        
                return newBody;
            }
Ejemplo n.º 2
0
        /// <summary>
        /// Records all of the helper types of the method body into this.helperTypes.
        /// </summary>
        /// <param name="methodBody"></param>
        public override void TraverseChildren(IMethodBody methodBody)
        {
            if (!(methodBody is SourceMethodBody))
            {
                // BCT omitted?
                return;
            }
            var  mutableBody = (SourceMethodBody)methodBody;
            var  block       = mutableBody.Block; //force decompilation
            bool denormalize = false;

            if (mutableBody.privateHelperTypesToRemove != null)
            {
                denormalize = true;
                foreach (var helperType in mutableBody.privateHelperTypesToRemove)
                {
                    Contract.Assume(helperType != null);
                    this.helperTypes[helperType.InternedKey] = helperType;
                }
            }
            if (mutableBody.privateHelperMethodsToRemove != null)
            {
                denormalize = true;
                foreach (var helperMethod in mutableBody.privateHelperMethodsToRemove.Values)
                {
                    Contract.Assume(helperMethod != null);
                    this.helperMethods[helperMethod.InternedKey] = helperMethod;
                }
            }
            if (mutableBody.privateHelperFieldsToRemove != null)
            {
                denormalize = true;
                foreach (var helperField in mutableBody.privateHelperFieldsToRemove)
                {
                    this.helperFields[helperField] = helperField;
                }
            }
            if (denormalize)
            {
                var mutableMethod    = (MethodDefinition)mutableBody.MethodDefinition;
                var denormalizedBody = new Microsoft.Cci.MutableCodeModel.SourceMethodBody(this.host, this.sourceLocationProvider);
                denormalizedBody.LocalsAreZeroed  = mutableBody.LocalsAreZeroed;
                denormalizedBody.IsNormalized     = false;
                denormalizedBody.Block            = block;
                denormalizedBody.MethodDefinition = mutableMethod;
                mutableMethod.Body = denormalizedBody;
            }
        }
Ejemplo n.º 3
0
    /// <summary>
    /// Given a method definition and a block of statements that represents the Block property of the body of the method,
    /// returns a SourceMethod with a body that no longer has any yield statements or anonymous delegate expressions.
    /// The given block of statements is mutated in place.
    /// </summary>
    public SourceMethodBody GetNormalizedSourceMethodBodyFor(IMethodDefinition method, IBlockStatement body) {
      var finder = new ClosureFinder(method, this.host);
      finder.Traverse(body);

      var privateHelperTypes = new List<ITypeDefinition>();
      if (finder.foundYield) {
        this.isIteratorBody = true;
        body = this.GetNormalizedIteratorBody(body, method, privateHelperTypes);
      }
      SourceMethodBody result = new SourceMethodBody(this.host, this.sourceLocationProvider);
      result.Block = body;
      result.MethodDefinition = method;
      result.IsNormalized = true;
      result.LocalsAreZeroed = true;
      result.PrivateHelperTypes = privateHelperTypes;

      return result;
    }
Ejemplo n.º 4
0
 /// <summary>
 /// Create the generic version of the GetEnumerator for the iterator closure class. 
 /// </summary>
 /// <param name="iteratorClosure"></param>
 private void CreateGetEnumeratorMethodGeneric(IteratorClosureInformation iteratorClosure) {
   // Metadata
   MethodDefinition genericGetEnumerator = new MethodDefinition() {
     Attributes = new List<ICustomAttribute>(1),
     InternFactory = this.host.InternFactory,
     Name = this.host.NameTable.GetNameFor("System.Collections.Generic.IEnumerable<" + iteratorClosure.ElementType.ToString()+">.GetEnumerator")
   };
   CustomAttribute debuggerHiddenAttribute = new CustomAttribute() { Constructor = this.DebuggerHiddenCtor };
   genericGetEnumerator.Attributes.Add(debuggerHiddenAttribute);
   genericGetEnumerator.CallingConvention |= CallingConvention.HasThis;
   genericGetEnumerator.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
   genericGetEnumerator.Visibility = TypeMemberVisibility.Public;
   genericGetEnumerator.Type = iteratorClosure.GenericIEnumeratorInterface;
   genericGetEnumerator.IsVirtual = true;
   genericGetEnumerator.IsNewSlot = true;
   genericGetEnumerator.IsHiddenBySignature = true;
   genericGetEnumerator.IsSealed = true;
   // Membership 
   iteratorClosure.GenericGetEnumerator = genericGetEnumerator;
   IMethodReference genericGetEnumeratorOriginal = Dummy.MethodReference;
   // Explicit implementation of IEnumerable<T>.GetEnumerator
   foreach (var memref in iteratorClosure.GenericIEnumerableInterface.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("GetEnumerator"), false)) {
     IMethodReference mref = memref as IMethodReference;
     if (mref != null) { genericGetEnumeratorOriginal = mref; break; }
   }
   var genericGetEnumeratorImp = new MethodImplementation() {
     ContainingType = iteratorClosure.ClosureDefinition,
     ImplementingMethod = genericGetEnumerator,
     ImplementedMethod = genericGetEnumeratorOriginal
   };
   iteratorClosure.ClosureDefinition.ExplicitImplementationOverrides.Add(genericGetEnumeratorImp);
   // Body
   var block = GetBodyOfGenericGetEnumerator(iteratorClosure);
   var body = new SourceMethodBody(this.host, this.sourceLocationProvider);
   body.LocalsAreZeroed = true;
   body.IsNormalized = true;
   body.Block = block;
   body.MethodDefinition = genericGetEnumerator;
   genericGetEnumerator.Body = body;
 }
Ejemplo n.º 5
0
 /// <summary>
 /// DisposeMethod method. Currently the method body does nothing. 
 /// </summary>
 private void CreateDisposeMethod(IteratorClosureInformation iteratorClosure) {
   MethodDefinition disposeMethod = new MethodDefinition() {
     Attributes = new List<ICustomAttribute>(1),
     InternFactory = this.host.InternFactory,
     Name = this.host.NameTable.GetNameFor("Dispose")
   };
   disposeMethod.Attributes.Add(new CustomAttribute() { Constructor = this.debuggerHiddenCtor });
   disposeMethod.CallingConvention |= CallingConvention.HasThis;
   disposeMethod.Visibility = TypeMemberVisibility.Public;
   disposeMethod.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
   disposeMethod.Type = this.host.PlatformType.SystemVoid;
   disposeMethod.IsVirtual = true;
   disposeMethod.IsNewSlot = true;
   disposeMethod.IsHiddenBySignature = true;
   disposeMethod.IsSealed = true;
   // Add disposeMethod to parent's member list. 
   iteratorClosure.DisposeMethod = disposeMethod;
   // Explicitly implements IDisposable's dispose. 
   IMethodReference disposeImplemented = Dummy.MethodReference;
   foreach (var memref in iteratorClosure.DisposableInterface.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("Dispose"), false)) {
     IMethodReference mref = memref as IMethodReference;
     if (mref != null) {
       disposeImplemented = mref;
       break;
     }
   }
   MethodImplementation disposeImp = new MethodImplementation() {
     ContainingType = iteratorClosure.ClosureDefinition,
     ImplementedMethod = disposeImplemented,
     ImplementingMethod = disposeMethod
   };
   iteratorClosure.ClosureDefinition.ExplicitImplementationOverrides.Add(disposeImp);
   // Body is a sole return. 
   BlockStatement block = new BlockStatement();
   block.Statements.Add(new ReturnStatement() {
     Expression = null,
     Locations = iteratorClosure.ClosureDefinition.Locations
   });
   SourceMethodBody body = new SourceMethodBody(this.host, this.sourceLocationProvider);
   body.LocalsAreZeroed = true;
   body.IsNormalized = true;
   body.Block = block;
   body.MethodDefinition = disposeMethod;
   disposeMethod.Body = body;
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Rewrites the children of the the given source method body.
 /// </summary>
 public virtual void RewriteChildren(SourceMethodBody sourceMethodBody)
 {
     sourceMethodBody.Block = this.Rewrite((BlockStatement)sourceMethodBody.Block);
 }
    /// <summary>
    /// Creates a new nested type definition with a default constructor and no other members and adds it to this.closureClasses.
    /// If this.method is generic, then the closure class is generic as well, with the same
    /// number of type parameters (constrained in the same way) as the generic method.
    /// Initializes this.currentClosure, this.currentClosureInstance and this.currentClosureSelfInstance.
    /// </summary>
    private void CreateClosureClass() {
      if (this.closureClasses == null) this.closureClasses = new List<ITypeDefinition>();
      NestedTypeDefinition closure = new NestedTypeDefinition();
      var containingType = this.method.ContainingTypeDefinition;
      closure.Name = this.host.NameTable.GetNameFor("<"+this.method.Name+">c__DisplayClass"+closure.GetHashCode());
      closure.Attributes = new List<ICustomAttribute>(1) { this.compilerGenerated };
      closure.BaseClasses = new List<ITypeReference>(1) { this.host.PlatformType.SystemObject };
      closure.ContainingTypeDefinition = containingType;
      closure.Fields = new List<IFieldDefinition>();
      closure.InternFactory = this.host.InternFactory;
      closure.IsBeforeFieldInit = true;
      closure.IsClass = true;
      closure.IsSealed = true;
      closure.Layout = LayoutKind.Auto;
      closure.Methods = new List<IMethodDefinition>();
      closure.StringFormat = StringFormatKind.Ansi;
      closure.Visibility = TypeMemberVisibility.Private;
      this.closureClasses.Add(closure);
      this.currentClosureClass = closure;

      //generics
      if (this.method.IsGeneric) {
        Dictionary<ushort, IGenericParameterReference> genericMethodParameterMap = new Dictionary<ushort, IGenericParameterReference>();
        this.genericMethodParameterMap = genericMethodParameterMap;
        bool foundConstraints = false;
        var genericTypeParameters = new List<IGenericTypeParameter>(this.method.GenericParameterCount);
        closure.GenericParameters = genericTypeParameters;
        foreach (var genericMethodParameter in this.method.GenericParameters) {
          var copyOfGenericMethodParameter = this.copier.Copy(genericMethodParameter); //so that we have mutable constraints to rewrite
          var genericTypeParameter = new GenericTypeParameter();
          genericTypeParameter.Copy(copyOfGenericMethodParameter, this.host.InternFactory);
          genericTypeParameter.DefiningType = closure;
          if (genericTypeParameter.Constraints != null && genericTypeParameter.Constraints.Count > 0) foundConstraints = true;
          genericTypeParameters.Add(genericTypeParameter);
          genericMethodParameterMap.Add(copyOfGenericMethodParameter.Index, genericTypeParameter);
        }
        if (foundConstraints) {
          //Fix up any self references that might lurk inside constraints.
          closure.GenericParameters = new GenericParameterRewriter(this.host, genericMethodParameterMap).Rewrite(genericTypeParameters);
        }
        var instanceType = closure.InstanceType;
        var genericArguments = IteratorHelper.GetConversionEnumerable<IGenericMethodParameter, ITypeReference>(this.method.GenericParameters);
        this.currentClosureInstance = new Immutable.GenericTypeInstanceReference(instanceType.GenericType, genericArguments, this.host.InternFactory);
        this.currentClosureSelfInstance = instanceType;
      } else {
        //if any of the containing types are generic, we need an instance or a specialized nested type.
        this.currentClosureInstance = NestedTypeDefinition.SelfInstance(closure, this.host.InternFactory);
        this.currentClosureSelfInstance = this.currentClosureInstance;
      }

      //default constructor
      var block = new BlockStatement();
      block.Statements.Add(
        new ExpressionStatement() {
          Expression = new MethodCall() {
            ThisArgument = new ThisReference() { Type = this.currentClosureSelfInstance },
            MethodToCall = this.objectCtor,
            Type = this.host.PlatformType.SystemVoid
          }
        }
      );

      var constructorBody = new SourceMethodBody(this.host, this.sourceLocationProvider) {
        LocalsAreZeroed = true,
        IsNormalized = true,
        Block = block
      };

      var defaultConstructor = new MethodDefinition() {
        Body = constructorBody,
        ContainingTypeDefinition = closure,
        CallingConvention = CallingConvention.HasThis,
        InternFactory = this.host.InternFactory,
        IsCil = true,
        IsHiddenBySignature = true,
        IsRuntimeSpecial = true,
        IsSpecialName = true,
        Name = this.host.NameTable.Ctor,
        Type = this.host.PlatformType.SystemVoid,
        Visibility = TypeMemberVisibility.Public,
      };
      constructorBody.MethodDefinition = defaultConstructor;
      closure.Methods.Add(defaultConstructor);

    }
Ejemplo n.º 8
0
    private NamespaceTypeDefinition CreateContractReferenceAssemblyAttribute(IRootUnitNamespace rootNs) {

      var internFactory = this.host.InternFactory;
      var nameTable = this.host.NameTable;

      var contractReferenceAssemblyAttributeName = nameTable.GetNameFor("ContractReferenceAssemblyAttribute");
      var contractNamespaceName = nameTable.GetNameFor("System.Diagnostics.Contracts");

      #region Define type
      CustomAttribute compilerGeneratedAttribute = new CustomAttribute() {
        Constructor = new Microsoft.Cci.MethodReference(
          this.host,
          this.compilerGeneratedAttributeType,
          CallingConvention.HasThis,
          this.systemVoidType,
          this.host.NameTable.Ctor,
          0)
      };

      var contractsNs = new NestedUnitNamespace() {
        ContainingUnitNamespace = rootNs,
        Name = contractNamespaceName,
      };
      NamespaceTypeDefinition result = new NamespaceTypeDefinition() {
        Name = contractReferenceAssemblyAttributeName,
        Attributes = new List<ICustomAttribute>{ compilerGeneratedAttribute },
        BaseClasses = new List<ITypeReference>{ this.systemAttributeType },
        ContainingUnitNamespace = contractsNs, //unitNamespace,
        InternFactory = internFactory,
        IsBeforeFieldInit = true,
        IsClass = true,
        IsSealed = true,
        Methods = new List<IMethodDefinition>(),
        Layout = LayoutKind.Auto,
        StringFormat = StringFormatKind.Ansi,
      };
      contractsNs.Members.Add(result);
      this.allTypes.Add(result);
      #endregion Define type
      #region Define the ctor
      List<IStatement> statements = new List<IStatement>();
      SourceMethodBody body = new SourceMethodBody(this.host) {
        LocalsAreZeroed = true,
        Block = new BlockStatement() { Statements = statements },
      };
      MethodDefinition ctor = new MethodDefinition() {
        Body = body,
        CallingConvention = CallingConvention.HasThis,
        ContainingTypeDefinition = result,
        InternFactory = internFactory,
        IsRuntimeSpecial = true,
        IsStatic = false,
        IsSpecialName = true,
        Name = nameTable.Ctor,
        Type = this.systemVoidType,
        Visibility = TypeMemberVisibility.Public,
      };
      body.MethodDefinition = ctor;
      var thisRef = new ThisReference() { Type = result, };
      // base();
      foreach (var baseClass in result.BaseClasses) {
        var baseCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() {
          CallingConvention = CallingConvention.HasThis,
          ContainingType = baseClass,
          GenericParameterCount = 0,
          InternFactory = this.host.InternFactory,
          Name = nameTable.Ctor,
          Type = this.systemVoidType,
        };
        statements.Add(
          new ExpressionStatement() {
            Expression = new MethodCall() {
              MethodToCall = baseCtor,
              IsStaticCall = false, // REVIEW: Is this needed in addition to setting the ThisArgument?
              ThisArgument = new ThisReference() { Type = result, },
              Type = this.systemVoidType, // REVIEW: Is this the right way to do this?
              Arguments = new List<IExpression>(),
            }
          }
          );
        break;
      }

      // return;
      statements.Add(new ReturnStatement());
      result.Methods.Add(ctor);
      #endregion Define the ctor
      return result;
    }
Ejemplo n.º 9
0
    /// <summary>
    /// Returns a method whose body is empty, but which can be replaced with the real body when it is
    /// available.
    /// </summary>
    /// <remarks>
    /// Public because it needs to get called when an anonymous delegate is encountered
    /// while translating a method body. Just mapping the anonymous delegate doesn't
    /// provide the information needed. The parameters of a method reference are not
    /// IParameterDefinitions.
    /// </remarks>
    public MethodDefinition TranslateMetadata(R.IMethodSymbol methodSymbol) {
      Contract.Requires(methodSymbol != null);
      Contract.Ensures(Contract.Result<MethodDefinition>() != null);

      var containingType = (ITypeDefinition)this.typeSymbolCache[methodSymbol.ContainingType];
      var isConstructor = methodSymbol.MethodKind == R.CommonMethodKind.Constructor;
      List<IParameterDefinition> parameters = new List<IParameterDefinition>();

      var m = new MethodDefinition() {
        CallingConvention = methodSymbol.IsStatic ? CallingConvention.Default : CallingConvention.HasThis,
        ContainingTypeDefinition = containingType,
        InternFactory = this.host.InternFactory,
        IsHiddenBySignature = true, // REVIEW
        IsNewSlot = containingType.IsInterface, // REVIEW
        IsRuntimeSpecial = isConstructor,
        IsSpecialName = isConstructor,
        IsStatic = methodSymbol.IsStatic,
        IsVirtual = containingType.IsInterface, // REVIEW: Why doesn't using methodSymbol.Virtual work for interface methods?
        Locations = Helper.WrapLocations(methodSymbol.Locations),
        Name = this.nameTable.GetNameFor(methodSymbol.Name),
        Parameters = parameters,
        Type = this.Map(methodSymbol.ReturnType),
        Visibility = this.Map(methodSymbol.DeclaredAccessibility),
      };

      // IMPORTANT: Have to add it to the cache before doing anything else because it may
      // get looked up if it is generic and a parameter's type involves the generic
      // method parameter.
      this.methodSymbolCache.Add(methodSymbol, m);

      #region Define the generic parameters
      if (methodSymbol.IsGenericMethod) {
      var genericParameters = new List<IGenericMethodParameter>();
      foreach (var gp in methodSymbol.TypeParameters) {
        var gp2 = this.CreateTypeDefinition(gp);
        genericParameters.Add((IGenericMethodParameter) gp2);
      }
      m.GenericParameters = genericParameters;
      }
      #endregion

      #region Define the parameters
      ushort i = 0;
      foreach (var p in methodSymbol.Parameters) {
        var p_prime = new ParameterDefinition() {
          ContainingSignature = m,
          IsByReference = p.RefKind == RefKind.Ref,
          IsIn = p.RefKind == RefKind.None,
          IsOut = p.RefKind == RefKind.Out,
          Name = nameTable.GetNameFor(p.Name),
          Type = this.Map(p.Type),
          Index = i++,
        };
        parameters.Add(p_prime);
      }
      #endregion Define the parameters

      #region Define default ctor, if needed
      if (/*methodSymbol.IsSynthesized &&*/ isConstructor) { // BUGBUG!!
        m.IsHiddenBySignature = true;
        m.IsRuntimeSpecial = true;
        m.IsSpecialName = true;
        var statements = new List<IStatement>();
        var body = new SourceMethodBody(this.host, null, null) {
          LocalsAreZeroed = true,
          Block = new BlockStatement() { Statements = statements },
        };
        var thisRef = new ThisReference() { Type = containingType, };
        // base();
        foreach (var baseClass in containingType.BaseClasses) {
          var baseCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() {
            CallingConvention = CallingConvention.HasThis,
            ContainingType = baseClass,
            GenericParameterCount = 0,
            InternFactory = this.host.InternFactory,
            Name = nameTable.Ctor,
            Type = this.host.PlatformType.SystemVoid,
          };
          statements.Add(
            new ExpressionStatement() {
              Expression = new MethodCall() {
                MethodToCall = baseCtor,
                IsStaticCall = false, // REVIEW: Is this needed in addition to setting the ThisArgument?
                ThisArgument = thisRef,
                Type = this.host.PlatformType.SystemVoid, // REVIEW: Is this the right way to do this?
                Arguments = new List<IExpression>(),
              }
            }
            );
          break;
        }
        // return;
        statements.Add(new ReturnStatement());
        body.MethodDefinition = m;
        m.Body = body;
      }
      #endregion

      return m;

    }
Ejemplo n.º 10
0
 /// <summary>
 /// Override the parent Substitute so that when we see a source method body, we will visit its statements.
 /// </summary>
 /// <param name="methodBody"></param>
 /// <returns></returns>
 public override IMethodBody Substitute(IMethodBody methodBody)
 {
     //^ requires (methodBody is ISourceMethodBody ==> this.cache.ContainsKeymethodBody.MethodDefinition));
       ISourceMethodBody sourceMethodBody = methodBody as ISourceMethodBody;
       if (sourceMethodBody != null) {
     SourceMethodBody mutableSourceMethodBody = new SourceMethodBody(this.host, this.sourceLocationProvider, null);
     mutableSourceMethodBody.Block = (IBlockStatement)this.Substitute(sourceMethodBody.Block);
     mutableSourceMethodBody.MethodDefinition = (IMethodDefinition)this.cache[methodBody.MethodDefinition];
     mutableSourceMethodBody.LocalsAreZeroed = methodBody.LocalsAreZeroed;
     return mutableSourceMethodBody;
       }
       return base.Substitute(methodBody);
 }
Ejemplo n.º 11
0
 /// <summary>
 /// Create the non-generic version of GetEnumerator and add it to the member list of iterator closure class. 
 /// </summary>
 private void CreateGetEnumeratorMethodNonGeneric(IteratorClosureInformation iteratorClosure) {
   // GetEnumerator non-generic version, which delegates to the generic version. 
   // Metadata
   MethodDefinition nongenericGetEnumerator = new MethodDefinition() {
     Attributes = new List<ICustomAttribute>(1),
     InternFactory = this.host.InternFactory,
     Name = this.host.NameTable.GetNameFor("System.Collections.IEnumerable.GetEnumerator")
   };
   nongenericGetEnumerator.Attributes.Add(
     new CustomAttribute() { Constructor = this.DebuggerHiddenCtor }
     );
   nongenericGetEnumerator.CallingConvention |= CallingConvention.HasThis;
   nongenericGetEnumerator.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
   nongenericGetEnumerator.Visibility = TypeMemberVisibility.Public;
   nongenericGetEnumerator.Type = iteratorClosure.NonGenericIEnumeratorInterface;
   nongenericGetEnumerator.IsVirtual = true;
   nongenericGetEnumerator.IsNewSlot = true;
   nongenericGetEnumerator.IsHiddenBySignature = true;
   nongenericGetEnumerator.IsSealed = true;
   iteratorClosure.NonGenericGetEnumerator = nongenericGetEnumerator;
   // Explicitly implements IEnumerable.GetEnumerator();
   IMethodReference nongenericGetEnumeratorOriginal = Dummy.MethodReference;
   foreach (var memref in iteratorClosure.NonGenericIEnumerableInterface.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("GetEnumerator"), false)) {
     IMethodReference mref = memref as IMethodReference;
     if (mref != null) { nongenericGetEnumeratorOriginal = mref; break; }
   }
   MethodImplementation nonGenericGetEnumeratorImp = new MethodImplementation() {
     ContainingType = iteratorClosure.ClosureDefinition,
     ImplementedMethod = nongenericGetEnumeratorOriginal,
     ImplementingMethod = nongenericGetEnumerator
   };
   iteratorClosure.ClosureDefinition.ExplicitImplementationOverrides.Add(nonGenericGetEnumeratorImp);
   // Body: call this.GetEnumerator (the generic version).
   BlockStatement block1 = new BlockStatement();
   block1.Statements.Add(new ReturnStatement() {
     Expression = new MethodCall() {
       IsStaticCall = false,
       MethodToCall = iteratorClosure.GenericGetEnumeratorReference,
       ThisArgument = new ThisReference(),
       Type = iteratorClosure.NonGenericIEnumeratorInterface
     }
   });
   SourceMethodBody body1 = new SourceMethodBody(this.host, this.sourceLocationProvider);
   body1.IsNormalized = true;
   body1.LocalsAreZeroed = true;
   body1.Block = block1;
   body1.MethodDefinition = nongenericGetEnumerator;
   nongenericGetEnumerator.Body = body1;
 }
Ejemplo n.º 12
0
        private IModule CreateNewDll(string assemblyName)
        {
            var host = new PeReader.DefaultHost();
            var core = host.LoadAssembly(host.CoreAssemblySymbolicIdentity);

            var assembly = new Assembly();
            assembly.Name = host.NameTable.GetNameFor(assemblyName);
            assembly.ModuleName = host.NameTable.GetNameFor(assemblyName + ".dll");
            assembly.Kind = ModuleKind.DynamicallyLinkedLibrary;
            assembly.PlatformType = host.PlatformType;
            assembly.TargetRuntimeVersion = core.TargetRuntimeVersion;
            assembly.AssemblyReferences.Add(core);

            foreach (var referencePath in model.ReferencePaths)
            {
                assembly.AssemblyReferences.Add(host.LoadUnitFrom(referencePath) as IAssembly);
            }

            var root = new RootUnitNamespace();
            root.Unit = assembly;
            assembly.UnitNamespaceRoot = root;

            var module = new NamespaceTypeDefinition();
            module.Name = host.NameTable.GetNameFor("<Module>");
            module.IsClass = true;
            module.InternFactory = host.InternFactory;
            module.ContainingUnitNamespace = root;

            assembly.AllTypes.Add(module);

            var rootTypeNamespace = new NestedUnitNamespace();
            rootTypeNamespace.Name = host.NameTable.GetNameFor(assembly.Name.Value);

            root.Members.Add(rootTypeNamespace);

            foreach (var classConfiguration in model.Classes)
            {
                var newClass = new NamespaceTypeDefinition();
                newClass.IsAbstract = classConfiguration.IsAbstract;
                newClass.IsClass = true;
                newClass.BaseClasses = new List<ITypeReference>{ host.PlatformType.SystemObject };
                newClass.IsPublic = true;

                if (classConfiguration.IsStatic)
                {
                    newClass.IsStatic = true;
                    newClass.IsAbstract = true;
                    newClass.IsSealed = true;
                }

                if (!String.IsNullOrEmpty(classConfiguration.Namespace))
                {
                    NestedUnitNamespace classContainer = rootTypeNamespace;
                    var namespaceNames = classConfiguration.Namespace.Split('.');
                    foreach (var namespaceName in namespaceNames)
                    {
                        var existingMembers = classContainer.GetMembersNamed(host.NameTable.GetNameFor(namespaceName), false);
                        var nestedNamespace = new NestedUnitNamespace();
                        foreach (var existing in existingMembers)
                        {
                            if (existing as NestedUnitNamespace != null)
                            {
                                nestedNamespace = existing as NestedUnitNamespace;
                                break;
                            }
                        }

                        nestedNamespace.Name = host.NameTable.GetNameFor(namespaceName);
                        nestedNamespace.ContainingUnitNamespace = classContainer;
                        classContainer.Members.Add(nestedNamespace);
                        classContainer = nestedNamespace;
                    }

                    newClass.ContainingUnitNamespace = classContainer;
                }
                else
                {
                    newClass.ContainingUnitNamespace = rootTypeNamespace;
                }

                newClass.InternFactory = host.InternFactory;
                newClass.Name = host.NameTable.GetNameFor(classConfiguration.Name);
                newClass.Methods = new List<IMethodDefinition>(classConfiguration.Methods.Count);
                newClass.Fields = new List<IFieldDefinition>(classConfiguration.Fields.Count);

                foreach (var methodConfiguration in classConfiguration.Methods)
                {
                    var newMethod = new MethodDefinition();
                    newMethod.Name = host.NameTable.GetNameFor(methodConfiguration.Name);
                    newMethod.IsStatic = methodConfiguration.IsStatic;
                    newMethod.ContainingTypeDefinition = newClass;
                    newMethod.IsCil = true;
                    newMethod.IsHiddenBySignature = true;
                    newMethod.InternFactory = host.InternFactory;
                    newMethod.Visibility = TypeMemberVisibility.Public;
                    newMethod.Type = host.PlatformType.SystemVoid;

                    var newMethodParameters = new List<IParameterDefinition>();
                    foreach (var param in methodConfiguration.Parameters)
                    {
                        var newMethodParameter = new ParameterDefinition();
                        newMethodParameter.ContainingSignature = newMethod;
                        newMethodParameter.Index = (ushort)methodConfiguration.Parameters.IndexOf(param);
                        newMethodParameter.Name = host.NameTable.GetNameFor(param.Key);
                        newMethodParameter.Type = new UnitReflector(host).Get(param.Value);

                        newMethodParameters.Add(newMethodParameter);
                    }

                    newMethod.Parameters = newMethodParameters;

                    var methodBody = new SourceMethodBody(host, null);
                    methodBody.MethodDefinition = newMethod;
                    methodBody.LocalsAreZeroed = true;

                    var block = new BlockStatement();
                    var returnStatement = new ReturnStatement();

                    if (methodConfiguration.ReturnType != null)
                    {
                        newMethod.Type = new UnitReflector(host).Get(methodConfiguration.ReturnType);
                        returnStatement.Expression = new CompileTimeConstant();
                    }

                    if (methodConfiguration.MethodBody != null)
                    {
                        var codeBuilder = new CodeBuilder(host, newMethod.Parameters);
                        methodConfiguration.MethodBody(codeBuilder);

                        foreach (var statement in codeBuilder.Statements)
                        {
                            block.Statements.Add(statement);
                        }
                    }

                    // "Stack must be empty on return from a void method"
                    //returnStatement.Expression = new CompileTimeConstant();
                    //block.Statements.Add(returnStatement);

                    methodBody.Block = block;

                    newMethod.Body = methodBody;

                    newClass.Methods.Add(newMethod);
                }

                foreach (var field in classConfiguration.Fields)
                {
                    var fieldDefinition = new FieldDefinition();
                    fieldDefinition.ContainingTypeDefinition = newClass;
                    fieldDefinition.InternFactory = host.InternFactory;
                    fieldDefinition.IsReadOnly = field.IsReadonly;
                    fieldDefinition.IsStatic = field.IsStatic;
                    fieldDefinition.Name = host.NameTable.GetNameFor(field.Name);
                    fieldDefinition.Type = new UnitReflector(host).Get(field.FieldType);
                    fieldDefinition.Visibility = field.Accessibility.ToTypeMemberVisibility();

                    newClass.Fields.Add(fieldDefinition);
                }

                assembly.AllTypes.Add(newClass);
            }

            using (var dll = File.Create(assemblyName + ".dll"))
            {
                PeWriter.WritePeToStream(assembly, host, dll);
                dll.Close();
            }

            return assembly;
        }
Ejemplo n.º 13
0
 /// <summary>
 /// If the <paramref name="typeDefinition"/> has a type contract, generate a
 /// contract invariant method and add it to the Methods of the <paramref name="typeDefinition"/>.
 /// </summary>
 private void VisitTypeDefinition(ITypeDefinition typeDefinition) {
   ITypeContract typeContract = this.contractProvider.GetTypeContractFor(typeDefinition);
   if (typeContract != null) {
     #region Define the method
     List<IStatement> statements = new List<IStatement>();
     var methodBody = new SourceMethodBody(this.host) {
       LocalsAreZeroed = true,
       Block = new BlockStatement() { Statements = statements }
     };
     List<ICustomAttribute> attributes = new List<ICustomAttribute>();
     MethodDefinition m = new MethodDefinition() {
       Attributes = attributes,
       Body = methodBody,
       CallingConvention = CallingConvention.HasThis,
       ContainingTypeDefinition = typeDefinition,
       InternFactory = this.host.InternFactory,
       IsStatic = false,
       Name = this.host.NameTable.GetNameFor("$InvariantMethod$"),
       Type = systemVoid,
       Visibility = TypeMemberVisibility.Private,
     };
     methodBody.MethodDefinition = m;
     #region Add calls to Contract.Invariant
     foreach (var inv in typeContract.Invariants) {
       var methodCall = new MethodCall() {
         Arguments = new List<IExpression> { inv.Condition, },
         IsStaticCall = true,
         MethodToCall = this.contractProvider.ContractMethods.Invariant,
         Type = systemVoid,
         Locations = new List<ILocation>(inv.Locations),
       };
       ExpressionStatement es = new ExpressionStatement() {
         Expression = methodCall
       };
       statements.Add(es);
     }
     statements.Add(new ReturnStatement());
     #endregion
     #region Add [ContractInvariantMethod]
     var contractInvariantMethodType = new Immutable.NamespaceTypeReference(
       this.host,
       this.host.PlatformType.SystemDiagnosticsContractsContract.ContainingUnitNamespace,
       this.host.NameTable.GetNameFor("ContractInvariantMethodAttribute"),
       0,
       false,
       false,
       true,
       PrimitiveTypeCode.NotPrimitive
       );
     var contractInvariantMethodCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() {
       CallingConvention = CallingConvention.HasThis,
       ContainingType = contractInvariantMethodType,
       GenericParameterCount = 0,
       InternFactory = this.host.InternFactory,
       Name = host.NameTable.Ctor,
       Type = host.PlatformType.SystemVoid,
     };
     var contractInvariantMethodAttribute = new CustomAttribute();
     contractInvariantMethodAttribute.Constructor = contractInvariantMethodCtor;
     attributes.Add(contractInvariantMethodAttribute);
     #endregion
     var namedTypeDefinition = (NamedTypeDefinition)typeDefinition;
     var newMethods = new List<IMethodDefinition>(namedTypeDefinition.Methods == null ? 1 : namedTypeDefinition.Methods.Count() + 1);
     if (namedTypeDefinition.Methods != null) {
       foreach (var meth in namedTypeDefinition.Methods) {
         if (!ContractHelper.IsInvariantMethod(this.host, meth))
           newMethods.Add(meth);
       }
     }
     namedTypeDefinition.Methods = newMethods;
     namedTypeDefinition.Methods.Add(m);
     #endregion Define the method
   }
 }
Ejemplo n.º 14
0
 public override void RewriteChildren(MethodDefinition methodDefinition) {
   IMethodContract methodContract = this.contractProvider.GetMethodContractFor(methodDefinition);
   if (methodContract == null) return;
   ISourceMethodBody sourceMethodBody = methodDefinition.Body as ISourceMethodBody;
   if (sourceMethodBody == null) return;
   List<IStatement> contractStatements = new List<IStatement>();
   foreach (var precondition in methodContract.Preconditions) {
     var methodCall = new MethodCall() {
       Arguments = new List<IExpression> { precondition.Condition, },
       IsStaticCall = true,
       MethodToCall = this.contractProvider.ContractMethods.Requires,
       Type = systemVoid,
       Locations = new List<ILocation>(precondition.Locations),
     };
     ExpressionStatement es = new ExpressionStatement() {
       Expression = methodCall
     };
     contractStatements.Add(es);
   }
   foreach (var postcondition in methodContract.Postconditions) {
     var methodCall = new MethodCall() {
       Arguments = new List<IExpression> { this.Rewrite(postcondition.Condition), },
       IsStaticCall = true,
       MethodToCall = this.contractProvider.ContractMethods.Ensures,
       Type = systemVoid,
       Locations = new List<ILocation>(postcondition.Locations),
     };
     ExpressionStatement es = new ExpressionStatement() {
       Expression = methodCall
     };
     contractStatements.Add(es);
   }
   List<IStatement> existingStatements = new List<IStatement>(sourceMethodBody.Block.Statements);
   existingStatements = this.Rewrite(existingStatements);
   // keep the call to the base constructor at the top
   if (methodDefinition.IsConstructor && existingStatements.Count > 0) {
     contractStatements.Insert(0, existingStatements[0]);
     existingStatements.RemoveAt(0);
   }
   contractStatements.AddRange(existingStatements); // replaces assert/assume
   var newSourceMethodBody = new SourceMethodBody(this.host, this.sourceLocationProvider) {
     Block = new BlockStatement() {
       Statements = contractStatements,
     },
     IsNormalized = false,
     LocalsAreZeroed = sourceMethodBody.LocalsAreZeroed,
     MethodDefinition = methodDefinition,
   };
   methodDefinition.Body = newSourceMethodBody;
   return;
 }
Ejemplo n.º 15
0
    private static NamespaceTypeDefinition DefineMethodHashAttributeType(HostEnvironment host, RootUnitNamespace rootUnitNamespace) {
      Contract.Requires(host != null);
      var internFactory = host.InternFactory;

      #region Define the type
      var methodHashAttributeType = new NamespaceTypeDefinition() {
        BaseClasses = new List<ITypeReference> { host.PlatformType.SystemAttribute, },
        ContainingUnitNamespace = rootUnitNamespace,
        InternFactory = internFactory,
        //IsBeforeFieldInit = true,
        IsClass = true,
        IsPublic = true,
        //IsSealed = true,
        Methods = new List<IMethodDefinition>(1),
        Name = host.NameTable.GetNameFor("MethodHashAttribute"),
        //Layout = LayoutKind.Auto,
        //StringFormat = StringFormatKind.Ansi,
      };
      #endregion

      #region Define the ctor
      var systemVoidType = host.PlatformType.SystemVoid;
      List<IStatement> statements = new List<IStatement>();
      SourceMethodBody body = new SourceMethodBody(host) {
        LocalsAreZeroed = true,
        Block = new BlockStatement() { Statements = statements },
      };

      var ctor = new MethodDefinition() {
        Body = body,
        CallingConvention = CallingConvention.HasThis,
        ContainingTypeDefinition = methodHashAttributeType,
        InternFactory = internFactory,
        IsRuntimeSpecial = true,
        IsStatic = false,
        IsSpecialName = true,
        Name = host.NameTable.Ctor,
        Type = systemVoidType,
        Visibility = TypeMemberVisibility.Public,
      };
      var systemStringType = host.PlatformType.SystemString;
      var systemIntType = host.PlatformType.SystemInt32;
      ctor.Parameters = new List<IParameterDefinition>(){
        new ParameterDefinition() {
          ContainingSignature = ctor,
          Name = host.NameTable.GetNameFor("a"),
          Type = systemStringType,
          Index = 0,
        },
        new ParameterDefinition() {
          ContainingSignature = ctor,
          Name = host.NameTable.GetNameFor("b"),
          Type = systemIntType,
          Index = 1,
        }
      };

      body.MethodDefinition = ctor;
      var thisRef = new ThisReference() { Type = methodHashAttributeType, };
      // base();
      foreach (var baseClass in methodHashAttributeType.BaseClasses) {
        var baseCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() {
          CallingConvention = CallingConvention.HasThis,
          ContainingType = baseClass,
          GenericParameterCount = 0,
          InternFactory = internFactory,
          Name = host.NameTable.Ctor,
          Type = systemVoidType,
        };
        statements.Add(
          new ExpressionStatement() {
            Expression = new MethodCall() {
              MethodToCall = baseCtor,
              IsStaticCall = false, // REVIEW: Is this needed in addition to setting the ThisArgument?
              ThisArgument = new ThisReference() { Type = methodHashAttributeType, },
              Type = systemVoidType, // REVIEW: Is this the right way to do this?
              Arguments = new List<IExpression>(),
            }
          }
          );
        break;
      }

      // return;
      statements.Add(new ReturnStatement());
      methodHashAttributeType.Methods.Add(ctor);
      #endregion Define the ctor
      return methodHashAttributeType;

    }
Ejemplo n.º 16
0
    /// <summary>
    /// Returns a shallow copy of the given source method body.
    /// </summary>
    /// <param name="sourceMethodBody"></param>
    public SourceMethodBody Copy(ISourceMethodBody sourceMethodBody) {
      Contract.Requires(sourceMethodBody != null);
      Contract.Ensures(Contract.Result<SourceMethodBody>() != null);

      var copy = new SourceMethodBody(this.targetHost, this.sourceLocationProvider, this.localScopeProvider);
      copy.Block = sourceMethodBody.Block;
      copy.LocalsAreZeroed = sourceMethodBody.LocalsAreZeroed;
      copy.MethodDefinition = sourceMethodBody.MethodDefinition;
      return copy;
    }
Ejemplo n.º 17
0
    /// <summary>
    /// Create two properties: object Current and T Current as the closure class implements both the 
    /// generic and non-generic version of ienumerator. 
    /// 
    /// Current Implementation generates getters, but not the property.
    /// </summary>
    /// <param name="iteratorClosure">Information about the closure created when compiling the current iterator method</param>
    private void CreateIteratorClosureProperties(IteratorClosureInformation iteratorClosure) {
      // Non-generic version of the get_Current, which returns the generic version of get_Current. 
      MethodDefinition getterNonGenericCurrent = new MethodDefinition() {
        Attributes = new List<ICustomAttribute>(1),
        InternFactory = this.host.InternFactory,
        Name = this.host.NameTable.GetNameFor("System.Collections.IEnumerator.get_Current")
      };
      CustomAttribute debuggerHiddenAttribute = new CustomAttribute();
      debuggerHiddenAttribute.Constructor = this.DebuggerHiddenCtor;
      getterNonGenericCurrent.Attributes.Add(debuggerHiddenAttribute);
      getterNonGenericCurrent.CallingConvention |= CallingConvention.HasThis;
      getterNonGenericCurrent.Visibility |= TypeMemberVisibility.Public;
      getterNonGenericCurrent.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
      getterNonGenericCurrent.Type = this.host.PlatformType.SystemObject;
      getterNonGenericCurrent.IsSpecialName = true;
      getterNonGenericCurrent.IsVirtual = true;
      getterNonGenericCurrent.IsNewSlot = true;
      getterNonGenericCurrent.IsHiddenBySignature = true;
      getterNonGenericCurrent.IsSealed = true;
      iteratorClosure.NonGenericGetCurrent = getterNonGenericCurrent;
      IMethodReference originalMethod = Dummy.MethodReference;
      foreach (ITypeMemberReference tref in iteratorClosure.NonGenericIEnumeratorInterface.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("get_Current"), false)) {
        originalMethod = tref as IMethodReference; if (originalMethod != null) break;
      }
      // assert originalMethod != Dummy
      MethodImplementation getterImplementation = new MethodImplementation() {
        ContainingType = iteratorClosure.ClosureDefinition,
        ImplementingMethod = getterNonGenericCurrent,
        ImplementedMethod = originalMethod
      };
      iteratorClosure.ClosureDefinition.ExplicitImplementationOverrides.Add(getterImplementation);

      List<IStatement> statements = new List<IStatement>();
      IFieldReference currentField = iteratorClosure.CurrentFieldReference;
      BoundExpression thisDotCurr = new BoundExpression() {
        Definition = currentField,
        Instance = new ThisReference(),
        Locations = iteratorClosure.ClosureDefinition.Locations,
        Type = currentField.Type
      };
      IExpression returnExpression;
      if (!iteratorClosure.ElementType.IsValueType && TypeHelper.TypesAreAssignmentCompatible(iteratorClosure.ElementType.ResolvedType, this.host.PlatformType.SystemObject.ResolvedType)) {
        returnExpression = thisDotCurr;
      } else {
        Conversion convertion = new Conversion() {
          CheckNumericRange = false,
          Type = this.host.PlatformType.SystemObject,
          TypeAfterConversion = getterNonGenericCurrent.Type,
          ValueToConvert = thisDotCurr
        };
        returnExpression = convertion;
      }
      ReturnStatement returnCurrent = new ReturnStatement() {
        Expression = returnExpression,
        Locations = iteratorClosure.ClosureDefinition.Locations
      };
      statements.Add(returnCurrent);
      BlockStatement block = new BlockStatement() { Statements = statements };
      SourceMethodBody body = new SourceMethodBody(this.host, this.sourceLocationProvider);
      body.IsNormalized = true;
      body.LocalsAreZeroed = true;
      body.Block = block;
      body.MethodDefinition = getterNonGenericCurrent;
      getterNonGenericCurrent.Body = body;

      // Create generic version of get_Current, the body of which is simply returning this.current.
      MethodDefinition getterGenericCurrent = new MethodDefinition() {
        Attributes = new List<ICustomAttribute>(1),
        InternFactory = this.host.InternFactory,
        Name = this.host.NameTable.GetNameFor("System.Collections.Generic.IEnumerator<" + iteratorClosure.ElementType.ToString() +">.get_Current")
      };
      getterGenericCurrent.Attributes.Add(debuggerHiddenAttribute);

      getterGenericCurrent.CallingConvention |= CallingConvention.HasThis;
      getterGenericCurrent.Visibility |= TypeMemberVisibility.Public;
      getterGenericCurrent.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
      getterGenericCurrent.Type = iteratorClosure.ElementType;
      getterGenericCurrent.IsSpecialName = true;
      getterGenericCurrent.IsVirtual = true;
      getterGenericCurrent.IsNewSlot = true;
      getterGenericCurrent.IsHiddenBySignature = true;
      getterGenericCurrent.IsSealed = true;
      iteratorClosure.GenericGetCurrent = getterGenericCurrent;
      originalMethod = Dummy.MethodReference;
      foreach (ITypeMemberReference tref in iteratorClosure.GenericIEnumeratorInterface.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("get_Current"), false)) {
        originalMethod = tref as IMethodReference; if (originalMethod != null) break;
      }
      MethodImplementation getterImplementation2 = new MethodImplementation() {
        ContainingType = iteratorClosure.ClosureDefinition,
        ImplementingMethod = getterGenericCurrent,
        ImplementedMethod = originalMethod
      };
      iteratorClosure.ClosureDefinition.ExplicitImplementationOverrides.Add(getterImplementation2);

      statements = new List<IStatement>();
      currentField = iteratorClosure.CurrentFieldReference;
      BoundExpression thisDotCurrent = new BoundExpression() {
        Definition = currentField, Instance = new ThisReference(), Locations = iteratorClosure.ClosureDefinition.Locations, Type = currentField.Type
      };
      returnCurrent = new ReturnStatement() {
        Expression = thisDotCurrent,
        Locations = iteratorClosure.ClosureDefinition.Locations
      };
      statements.Add(returnCurrent);
      block = new BlockStatement() { Statements = statements };
      body = new SourceMethodBody(this.host, this.sourceLocationProvider);
      body.LocalsAreZeroed = true;
      body.Block = block;
      body.MethodDefinition = getterGenericCurrent;
      getterGenericCurrent.Body = body;
    }
Ejemplo n.º 18
0
 /// <summary>
 /// Returns a shallow copy of the given source method body.
 /// </summary>
 /// <param name="sourceMethodBody"></param>
 public SourceMethodBody Copy(ISourceMethodBody sourceMethodBody)
 {
     var copy = new SourceMethodBody(this.targetHost, this.sourceLocationProvider);
       copy.Block = sourceMethodBody.Block;
       copy.LocalsAreZeroed = sourceMethodBody.LocalsAreZeroed;
       copy.MethodDefinition = sourceMethodBody.MethodDefinition;
       return copy;
 }
Ejemplo n.º 19
0
 /// <summary>
 /// Create the constuctor of the iterator class. The pseudo-code is: 
 /// 
 /// Ctor(int state) {
 ///   object.Ctor();
 ///   this.state = state;
 ///   this.threadid = Thread.CurrentThread.ManagedThreadId;
 /// }
 /// </summary>
 private void CreateIteratorClosureConstructor(IteratorClosureInformation iteratorClosure) {
   MethodDefinition constructor = new MethodDefinition() {
     InternFactory = this.host.InternFactory,
     Parameters = new List<IParameterDefinition>(1),
   };
   // Parameter
   ParameterDefinition stateParameter = new ParameterDefinition() {
     ContainingSignature = constructor,
     Index = 0,
     Name = this.host.NameTable.GetNameFor("state"),
     Type = this.host.PlatformType.SystemInt32
   };
   constructor.Parameters.Add(stateParameter);
   // Statements
   MethodCall baseConstructorCall = new MethodCall() { ThisArgument = new ThisReference(), MethodToCall = this.ObjectCtor, Type = this.host.PlatformType.SystemVoid };
   ExpressionStatement baseConstructorCallStatement = new ExpressionStatement() { Expression = baseConstructorCall };
   List<IStatement> statements = new List<IStatement>();
   ExpressionStatement thisDotStateEqState = new ExpressionStatement() {
     Expression = new Assignment() {
       Source = new BoundExpression() { Definition = stateParameter, Instance = null, Type = this.host.PlatformType.SystemInt32 },
       Target = new TargetExpression() { Instance = new ThisReference(), Type = this.host.PlatformType.SystemInt32, Definition = iteratorClosure.StateFieldReference },
       Type = this.host.PlatformType.SystemInt32
     }
   };
   ExpressionStatement thisThreadIdEqCurrentThreadId = new ExpressionStatement() {
     Expression = new Assignment() {
       Source = new MethodCall() {
         MethodToCall = this.ThreadDotManagedThreadId.Getter,
         ThisArgument = this.ThreadDotCurrentThread,
         Type = this.host.PlatformType.SystemInt32
       },
       Target = new TargetExpression() { Instance = new ThisReference(), Type = this.host.PlatformType.SystemInt32, Definition = iteratorClosure.InitThreadIdFieldReference },
       Type = this.host.PlatformType.SystemInt32
     }
   };
   statements.Add(baseConstructorCallStatement);
   statements.Add(thisDotStateEqState);
   statements.Add(thisThreadIdEqCurrentThreadId);
   BlockStatement block = new BlockStatement() { Statements = statements };
   SourceMethodBody body = new SourceMethodBody(this.host, this.sourceLocationProvider);
   body.LocalsAreZeroed = true;
   body.IsNormalized = true;
   body.Block = block;
   constructor.Body = body;
   body.MethodDefinition = constructor;
   // Metadata of the constructor
   constructor.CallingConvention = CallingConvention.HasThis;
   constructor.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
   constructor.IsCil = true;
   constructor.IsHiddenBySignature = true;
   constructor.IsRuntimeSpecial = true;
   constructor.IsSpecialName = true;
   constructor.Name = this.host.NameTable.Ctor;
   constructor.Type = this.host.PlatformType.SystemVoid;
   constructor.Visibility = TypeMemberVisibility.Public;
   iteratorClosure.Constructor = constructor;
 }
Ejemplo n.º 20
0
 /// <summary>
 /// Records all of the helper types of the method body into this.helperTypes.
 /// </summary>
 /// <param name="methodBody"></param>
 public override void TraverseChildren(IMethodBody methodBody)
 {
     var mutableBody = (SourceMethodBody)methodBody;
       var block = mutableBody.Block; //force decompilation
       bool denormalize = false;
       if (mutableBody.privateHelperTypesToRemove != null) {
     denormalize = true;
     foreach (var helperType in mutableBody.privateHelperTypesToRemove)
       this.helperTypes[helperType.InternedKey] = helperType;
       }
       if (mutableBody.privateHelperMethodsToRemove != null) {
     denormalize = true;
     foreach (var helperMethod in mutableBody.privateHelperMethodsToRemove.Values)
       this.helperMethods[helperMethod.InternedKey] = helperMethod;
       }
       if (mutableBody.privateHelperFieldsToRemove != null) {
     denormalize = true;
     foreach (var helperField in mutableBody.privateHelperFieldsToRemove.Values)
       this.helperFields[helperField] = helperField;
       }
       if (denormalize) {
     var mutableMethod = (MethodDefinition)mutableBody.MethodDefinition;
     var denormalizedBody = new Microsoft.Cci.MutableCodeModel.SourceMethodBody(this.host, this.sourceLocationProvider);
     denormalizedBody.LocalsAreZeroed = mutableBody.LocalsAreZeroed;
     denormalizedBody.IsNormalized = false;
     denormalizedBody.Block = block;
     denormalizedBody.MethodDefinition = mutableMethod;
     mutableMethod.Body = denormalizedBody;
       }
 }
Ejemplo n.º 21
0
    /// <summary>
    /// Create the MoveNext method. This method sets up metadata and calls TranslateIteratorMethodBodyToMoveNextBody
    /// to compile the body. 
    /// </summary>
    private void CreateMoveNextMethod(IteratorClosureInformation /*!*/ iteratorClosure, BlockStatement blockStatement) {
      // Method definition and metadata.
      MethodDefinition moveNext = new MethodDefinition() {
        InternFactory = this.host.InternFactory,
        Name = this.host.NameTable.GetNameFor("MoveNext")
      };
      moveNext.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
      moveNext.Visibility = TypeMemberVisibility.Private;
      moveNext.CallingConvention |= CallingConvention.HasThis;
      moveNext.Type = this.host.PlatformType.SystemBoolean;
      moveNext.InternFactory = this.host.InternFactory;
      moveNext.IsSealed = true;
      moveNext.IsVirtual = true;
      moveNext.IsHiddenBySignature = true;
      moveNext.IsNewSlot = true;
      iteratorClosure.MoveNext = moveNext;
      IMethodReference moveNextOriginal = Dummy.MethodReference;
      foreach (ITypeMemberReference tmref in iteratorClosure.NonGenericIEnumeratorInterface.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("MoveNext"), false)) {
        moveNextOriginal = tmref as IMethodReference;
        if (moveNextOriginal != null) break;
      }
      // Explicit method implementation
      MethodImplementation moveNextImp = new MethodImplementation() {
        ContainingType = iteratorClosure.ClosureDefinition,
        ImplementingMethod = moveNext,
        ImplementedMethod = moveNextOriginal
      };
      iteratorClosure.ClosureDefinition.ExplicitImplementationOverrides.Add(moveNextImp);

      SourceMethodBody body = new SourceMethodBody(this.host, this.sourceLocationProvider, null, this.iteratorLocalCount);
      IBlockStatement block = TranslateIteratorMethodBodyToMoveNextBody(iteratorClosure, blockStatement);
      moveNext.Body = body;
      body.IsNormalized = true;
      body.LocalsAreZeroed = true;
      body.Block = block;
      body.MethodDefinition = moveNext;
    }
        private SourceMethodBody GetBody(IMethodDefinition method, IMethodReference originalCall)
        {
            var body = new SourceMethodBody(host, null, null);
            body.MethodDefinition = method;
            body.LocalsAreZeroed = true;

            var block = new BlockStatement();
            body.Block = block;

            AddAlternativeInvocation(block, method, originalCall);

            return body;
        }
Ejemplo n.º 23
0
 /// <summary>
 /// Create the Reset method. Like in CSC, this method contains nothing. 
 /// </summary>
 private void CreateResetMethod(IteratorClosureInformation iteratorClosure) {
   // System.Collections.IEnumerator.Reset: Simply throws an exception
   MethodDefinition reset = new MethodDefinition() {
     Attributes = new List<ICustomAttribute>(1),
     InternFactory = this.host.InternFactory,
     Name = this.host.NameTable.GetNameFor("Reset")
   };
   CustomAttribute debuggerHiddenAttribute = new CustomAttribute() { Constructor = this.DebuggerHiddenCtor };
   reset.Attributes.Add(debuggerHiddenAttribute);
   reset.CallingConvention |= CallingConvention.HasThis;
   reset.Visibility = TypeMemberVisibility.Private;
   reset.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
   reset.Type = this.host.PlatformType.SystemVoid;
   reset.IsVirtual = true;
   reset.IsNewSlot = true;
   reset.IsHiddenBySignature = true;
   reset.IsSealed = true;
   iteratorClosure.Reset = reset;
   // explicitly state that this reset method implements IEnumerator's reset method. 
   IMethodReference resetImplemented = Dummy.MethodReference;
   foreach (var memref in iteratorClosure.NonGenericIEnumeratorInterface.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("Reset"), false)) {
     IMethodReference mref = memref as IMethodReference;
     if (mref != null) {
       resetImplemented = mref;
       break;
     }
   }
   MethodImplementation resetImp = new MethodImplementation() {
     ContainingType = iteratorClosure.ClosureDefinition,
     ImplementedMethod = resetImplemented,
     ImplementingMethod = reset
   };
   iteratorClosure.ClosureDefinition.ExplicitImplementationOverrides.Add(resetImp);
   List<IStatement> statements = new List<IStatement>();
   ReturnStatement returnCurrent = new ReturnStatement() {
     Expression = null,
     Locations = iteratorClosure.ClosureDefinition.Locations
   };
   statements.Add(returnCurrent);
   BlockStatement block = new BlockStatement() { Statements = statements };
   SourceMethodBody body = new SourceMethodBody(this.host, this.sourceLocationProvider);
   body.LocalsAreZeroed = true;
   body.IsNormalized = true;
   body.Block = block;
   body.MethodDefinition = reset;
   reset.Body = body;
 }
    /// <summary>
    /// Returns a reference to the closure method. If the method is generic, the reference is to an instantiation, 
    /// using the generic parameters of the current class as arguments.
    /// </summary>
    private IMethodReference CreateClosureMethod(AnonymousDelegate anonymousDelegate) {
      bool isPeerMethod = this.helperMembers != null && !this.anonymousDelegatesThatCaptureLocalsOrParameters.ContainsKey(anonymousDelegate);
      bool isStaticMethod = isPeerMethod && !this.anonymousDelegatesThatCaptureThis.ContainsKey(anonymousDelegate);
      var body = new SourceMethodBody(this.host, this.sourceLocationProvider) {
        Block = anonymousDelegate.Body,
        LocalsAreZeroed = true
      };
      var counter = isPeerMethod ? this.helperMembers.Count : this.anonymousDelegateCounter++;
      var prefix = "<"+this.method.Name.Value;
      prefix += isPeerMethod ? ">p__" : ">b__";
      var method = new MethodDefinition() {
        ContainingTypeDefinition = isPeerMethod ? this.method.ContainingTypeDefinition : this.currentClosureClass,
        Name = this.host.NameTable.GetNameFor(prefix+counter),
        Visibility = isPeerMethod ? TypeMemberVisibility.Private : TypeMemberVisibility.Public,
        Body = body,
        CallingConvention = isStaticMethod ? CallingConvention.Default : CallingConvention.HasThis,
        InternFactory = this.host.InternFactory,
        Parameters = anonymousDelegate.Parameters,
        Type = anonymousDelegate.ReturnType,
        IsCil = true,
        IsStatic = isStaticMethod,
        IsHiddenBySignature = true,
      };
      body.MethodDefinition = method;
      if (method.Parameters != null) {
        foreach (ParameterDefinition parameterDefinition in method.Parameters)
          parameterDefinition.ContainingSignature = method;
      }

      if (isPeerMethod) {
        this.helperMembers.Add(method);
        if (this.method.IsGeneric) this.MakeDelegateMethodGeneric(method);
        method.Attributes = new List<ICustomAttribute>(1);
        method.Attributes.Add(this.compilerGenerated);
      } else {
        this.currentClosureClass.Methods.Add(method);
        this.isInsideAnonymousMethod = true;
        this.RewriteChildren(method);
        this.isInsideAnonymousMethod = false;
      }

      IMethodReference methodReference = method;
      ITypeReference containingTypeDefinitionInstance = method.ContainingTypeDefinition;
      if (isPeerMethod)
        containingTypeDefinitionInstance = NamedTypeDefinition.SelfInstance((INamedTypeDefinition)method.ContainingTypeDefinition, this.host.InternFactory);
      if ((isPeerMethod && method.ContainingTypeDefinition != containingTypeDefinitionInstance) || 
          (!isPeerMethod && this.currentClosureClass != this.currentClosureInstance)) {
        methodReference = new MethodReference() {
          CallingConvention = method.CallingConvention,
          ContainingType = isPeerMethod ? containingTypeDefinitionInstance : this.currentClosureInstance,
          GenericParameterCount = method.GenericParameterCount,
          InternFactory = this.host.InternFactory,
          Name = method.Name,
          Parameters = methodReference.ParameterCount == 0 ? null : new List<IParameterTypeInformation>(methodReference.Parameters),
          Type = method.Type,
        };
      }

      if (!method.IsGeneric) return methodReference;
      return new GenericMethodInstanceReference() {
        CallingConvention = method.CallingConvention,
        ContainingType = method.ContainingTypeDefinition,
        GenericArguments = new List<ITypeReference>(IteratorHelper.GetConversionEnumerable<IGenericMethodParameter, ITypeReference>(method.GenericParameters)),
        GenericMethod = methodReference,
        InternFactory = this.host.InternFactory,
        Name = method.Name,
        Parameters = methodReference.ParameterCount == 0 ? null : new List<IParameterTypeInformation>(methodReference.Parameters),
        Type = method.Type,
      };
    }
Ejemplo n.º 25
0
 /// <summary>
 /// Visits the specified method body.
 /// </summary>
 /// <param name="methodBody">The method body.</param>
 public override IMethodBody Visit(IMethodBody methodBody)
 {
     ISourceMethodBody sourceMethodBody = methodBody as ISourceMethodBody;
       if (sourceMethodBody != null) {
     SourceMethodBody mutableSourceMethodBody = null;
     if (this.copyOnlyIfNotAlreadyMutable)
       mutableSourceMethodBody = sourceMethodBody as SourceMethodBody;
     if (mutableSourceMethodBody == null)
       mutableSourceMethodBody = new SourceMethodBody(this.host, this.sourceLocationProvider, null);
     mutableSourceMethodBody.Block = this.Visit(sourceMethodBody.Block);
     mutableSourceMethodBody.LocalsAreZeroed = methodBody.LocalsAreZeroed;
     mutableSourceMethodBody.MethodDefinition = this.GetCurrentMethod();
     return mutableSourceMethodBody;
       }
       return base.Visit(methodBody);
 }