public override IExpression Rewrite(ICreateDelegateInstance createDelegate)
 {
     var newDel = new CreateDelegateInstance(createDelegate);
     newDel.MethodToCallViaDelegate =
         CurrentMethod.ContainingTypeDefinition.Methods
         .First(m => m.ToString() == MutationTarget.PassInfo);
     return newDel;
 }
 /// <summary>
 /// Rewrites the given anonymous delegate expression.
 /// </summary>
 public override IExpression Rewrite(IAnonymousDelegate anonymousDelegate) {
   if (this.isInsideAnonymousMethod) return base.Rewrite(anonymousDelegate);
   IMethodReference method = this.CreateClosureMethod((AnonymousDelegate)anonymousDelegate);
   var createDelegate = new CreateDelegateInstance() {
     MethodToCallViaDelegate = method,
     Type = anonymousDelegate.Type
   };
   if (!method.IsStatic) {
     //TODO: if there is reason to believe the delegate will be constructed in a loop, but its closure is constructed before the loop, then cache the delegate in a local
     //that is in the same scope as the closure instance
     if (method.ContainingType == this.currentClosureInstance)
       createDelegate.Instance = this.currentClosureObject;
     else //non static peer method
       createDelegate.Instance = new ThisReference() {
         Type = NamedTypeDefinition.SelfInstance((INamedTypeDefinition)this.method.ContainingTypeDefinition, this.host.InternFactory)
       };
   } else if ((method.CallingConvention & CallingConvention.Generic) == 0) {
     //cache the delegate in a static field (we can only do this if method is not generic, i.e. when at most one instance will be created).
     var cache = this.CreateStaticCacheField(anonymousDelegate.Type);
     var boundField = new BoundExpression() { Definition = cache, Type = cache.Type };
     var statements = new List<IStatement>(1);
     var conditional = new ConditionalStatement() {
       Condition = new Equality() {
         LeftOperand = boundField,
         RightOperand = new CompileTimeConstant() { Value = null, Type = cache.Type },
         Type = this.host.PlatformType.SystemBoolean
       },
       TrueBranch = new ExpressionStatement() {
         Expression = new Assignment() {
           Target = new TargetExpression() { Definition = cache, Type = cache.Type },
           Source = createDelegate,
           Type = cache.Type
         }
       }
     };
     statements.Add(conditional);
     return new BlockExpression() {
       BlockStatement = new BlockStatement() { Statements = statements },
       Expression = boundField
     };
   }
   return createDelegate;
 }
 public override IExpression Rewrite(ICreateObjectInstance createObjectInstance) {
   var mutableCreateObjectInstance = createObjectInstance as CreateObjectInstance;
   if (mutableCreateObjectInstance != null && mutableCreateObjectInstance.Arguments.Count == 2) {
     AddressOf/*?*/ aexpr = mutableCreateObjectInstance.Arguments[1] as AddressOf;
     if (aexpr != null && aexpr.Expression.Definition is IMethodReference) {
       CreateDelegateInstance createDel = new CreateDelegateInstance();
       createDel.Instance = mutableCreateObjectInstance.Arguments[0];
       createDel.IsVirtualDelegate = aexpr.Expression.Instance != null;
       createDel.MethodToCallViaDelegate = (IMethodReference)aexpr.Expression.Definition;
       createDel.Locations = mutableCreateObjectInstance.Locations;
       createDel.Type = createObjectInstance.Type;
       return this.Rewrite(createDel);
     }
   }
   return base.Rewrite(createObjectInstance);
 }
Example #4
0
 /// <summary>
 /// Visits the specified create delegate instance.
 /// </summary>
 /// <param name="createDelegateInstance">The create delegate instance.</param>
 /// <returns></returns>
 protected virtual IExpression DeepCopy(CreateDelegateInstance createDelegateInstance)
 {
     createDelegateInstance.MethodToCallViaDelegate = this.Substitute(createDelegateInstance.MethodToCallViaDelegate);
       if (createDelegateInstance.Instance != null)
     createDelegateInstance.Instance = Substitute(createDelegateInstance.Instance);
       createDelegateInstance.Type = this.Substitute(createDelegateInstance.Type);
       return createDelegateInstance;
 }
Example #5
0
 /// <summary>
 /// Visits the specified create delegate instance.
 /// </summary>
 /// <param name="createDelegateInstance">The create delegate instance.</param>
 public override void Visit(ICreateDelegateInstance createDelegateInstance)
 {
     CreateDelegateInstance mutableCreateDelegateInstance = new CreateDelegateInstance(createDelegateInstance);
     this.resultExpression = this.myCodeCopier.DeepCopy(mutableCreateDelegateInstance);
 }
        private IExpression ConvertToAnonymousDelegate(CreateDelegateInstance createDelegateInstance, bool iteratorsHaveNotBeenDecompiled)
        {
            IMethodDefinition closureMethod = createDelegateInstance.MethodToCallViaDelegate.ResolvedMethod;
              if (this.sourceMethodBody.privateHelperMethodsToRemove == null) this.sourceMethodBody.privateHelperMethodsToRemove = new Dictionary<uint, IMethodDefinition>();
              IMethodBody closureMethodBody = UnspecializedMethods.GetMethodBodyFromUnspecializedVersion(closureMethod);
              AnonymousDelegate anonDel = new AnonymousDelegate();
              anonDel.CallingConvention = closureMethod.CallingConvention;
              var unspecializedClosureMethod = UnspecializedMethods.UnspecializedMethodDefinition(closureMethod);
              this.sourceMethodBody.privateHelperMethodsToRemove[unspecializedClosureMethod.InternedKey] = unspecializedClosureMethod;
              anonDel.Parameters = new List<IParameterDefinition>(unspecializedClosureMethod.Parameters);
              for (int i = 0, n = anonDel.Parameters.Count; i < n; i++) {
            IParameterDefinition closureMethodPar = UnspecializedParameterDefinition(anonDel.Parameters[i]);
            ParameterDefinition par = new ParameterDefinition();
            this.parameterMap.Add(closureMethodPar, par);
            par.Copy(closureMethodPar, this.host.InternFactory);
            par.ContainingSignature = anonDel;
            anonDel.Parameters[i] = par;
              }
              var alreadyDecompiledBody = closureMethodBody as SourceMethodBody;
              ISourceMethodBody anonDelSourceMethodBody = alreadyDecompiledBody;
              if (alreadyDecompiledBody == null) {
            var alreadyDecompiledBody2 = closureMethodBody as Microsoft.Cci.MutableCodeModel.SourceMethodBody;
            if (alreadyDecompiledBody2 == null) {
              var smb = new SourceMethodBody(closureMethodBody, this.sourceMethodBody.host,
            this.sourceMethodBody.sourceLocationProvider, this.sourceMethodBody.localScopeProvider, this.sourceMethodBody.options);
              anonDelSourceMethodBody = smb;
              anonDel.Body = smb.Block;
            } else {
              anonDel.Body = alreadyDecompiledBody2.Block;
              anonDelSourceMethodBody = alreadyDecompiledBody2;
            }
              } else {
            anonDel.Body = alreadyDecompiledBody.Block;
              }

              anonDel.ReturnValueIsByRef = closureMethod.ReturnValueIsByRef;
              if (closureMethod.ReturnValueIsModified)
            anonDel.ReturnValueCustomModifiers = new List<ICustomModifier>(closureMethod.ReturnValueCustomModifiers);
              anonDel.ReturnType = closureMethod.Type;
              anonDel.Type = createDelegateInstance.Type;

              if (iteratorsHaveNotBeenDecompiled && unspecializedClosureMethod.ContainingTypeDefinition.IsGeneric &&
            unspecializedClosureMethod.ContainingTypeDefinition.GenericParameterCount ==
            this.sourceMethodBody.MethodDefinition.ContainingTypeDefinition.GenericParameterCount) {
            var mapper = new GenericTypeParameterMapper(this.host, this.sourceMethodBody.MethodDefinition.ContainingTypeDefinition,
              unspecializedClosureMethod.ContainingTypeDefinition);
            mapper.Rewrite(anonDel);
              }

              BlockStatement bs = anonDel.Body as BlockStatement;
              if (bs != null) {
            var savedReferencedLabels = this.referencedLabels;
            this.referencedLabels = null;
            anonDel.Body = this.RemoveCompilationArtifacts(bs);
            this.referencedLabels = savedReferencedLabels;
              }
              IExpression result = anonDel;

              if (this.sourceMethodBody.MethodDefinition.IsGeneric) {
            if (unspecializedClosureMethod.IsGeneric)
              this.genericParameterMapper = new GenericMethodParameterMapper(this.host, this.sourceMethodBody.MethodDefinition, unspecializedClosureMethod);
            // If the closure method was not generic, then its containing type is generic
            // and the generic parameter mapper was created when the closure instance creation
            // was discovered at the beginning of this visitor.
            if (this.genericParameterMapper != null) {
              result = this.genericParameterMapper.Visit(result);
              foreach (var v in this.capturedBinding.Values) {
            // Do NOT visit any of the parameters in the table because that
            // will cause them to (possibly) have their types changed. But
            // they already have the correct type because they are parameters
            // of the enclosing method.
            // But the locals are ones that were created by this visitor so
            // they need their types updated.
            LocalDefinition ld = v.Definition as LocalDefinition;
            if (ld != null) {
              ld.Type = this.genericParameterMapper.Visit(ld.Type);
              ld.MethodDefinition = this.sourceMethodBody.MethodDefinition;
            }
              }
            }
              }

              return result;
        }
 public override IExpression Visit(CreateDelegateInstance createDelegateInstance)
 {
     IMethodDefinition delegateMethodDefinition = createDelegateInstance.MethodToCallViaDelegate.ResolvedMethod;
       delegateMethodDefinition = UnspecializedMethods.UnspecializedMethodDefinition(delegateMethodDefinition);
       ITypeReference delegateContainingType = createDelegateInstance.MethodToCallViaDelegate.ContainingType;
       delegateContainingType = UnspecializedMethods.AsUnspecializedTypeReference(delegateContainingType);
       INestedTypeDefinition/*?*/ dctnt = delegateContainingType.ResolvedType as INestedTypeDefinition;
       ITypeDefinition/*?*/ dctct = dctnt == null ? null : dctnt.ContainingTypeDefinition;
       if (this.restoreAnonymousDelegates &&
     (TypeHelper.TypesAreEquivalent(delegateContainingType.ResolvedType, this.containingType) || TypeHelper.TypesAreEquivalent(dctct, this.containingType)) &&
     UnspecializedMethods.IsCompilerGenerated(delegateMethodDefinition))
     return ConvertToAnonymousDelegate(createDelegateInstance, iteratorsHaveNotBeenDecompiled: false);
       // REVIEW: This is needed only when iterators are *not* decompiled. When they are, then that happens before this phase and the create delegate instances
       // have been moved into the iterator method (from the MoveNext method) so the above pattern catches everything.
       if (this.restoreAnonymousDelegates && UnspecializedMethods.IsCompilerGenerated(delegateMethodDefinition)) {
     var containingTypeAsNestedType = this.containingType as INestedTypeDefinition;
     if (containingTypeAsNestedType != null && dctnt != null && TypeHelper.TypesAreEquivalent(dctnt.ContainingType, containingTypeAsNestedType.ContainingType)) {
       return ConvertToAnonymousDelegate(createDelegateInstance, iteratorsHaveNotBeenDecompiled: true);
     }
       }
       return base.Visit(createDelegateInstance);
 }
Example #8
0
 /// <summary>
 /// Rewrites the children of the anonymous object creation expression.
 /// </summary>
 public virtual void RewriteChildren(CreateDelegateInstance createDelegateInstance)
 {
     this.RewriteChildren((Expression)createDelegateInstance);
       if (createDelegateInstance.Instance != null)
     createDelegateInstance.Instance = this.Rewrite(createDelegateInstance.Instance);
       createDelegateInstance.MethodToCallViaDelegate = this.Rewrite(createDelegateInstance.MethodToCallViaDelegate);
 }
Example #9
0
 /// <summary>
 /// Visits the specified create delegate instance.
 /// </summary>
 /// <param name="createDelegateInstance">The create delegate instance.</param>
 /// <returns></returns>
 public virtual IExpression Visit(CreateDelegateInstance createDelegateInstance)
 {
     createDelegateInstance.MethodToCallViaDelegate = this.Visit(createDelegateInstance.MethodToCallViaDelegate);
       if (createDelegateInstance.Instance != null)
     createDelegateInstance.Instance = Visit(createDelegateInstance.Instance);
       createDelegateInstance.Type = this.Visit(createDelegateInstance.Type);
       return createDelegateInstance;
 }
Example #10
0
 /// <summary>
 /// Visits the specified create delegate instance.
 /// </summary>
 /// <param name="createDelegateInstance">The create delegate instance.</param>
 public override void Visit(ICreateDelegateInstance createDelegateInstance)
 {
     CreateDelegateInstance mutableCreateDelegateInstance = createDelegateInstance as CreateDelegateInstance;
     if (alwaysMakeACopy || mutableCreateDelegateInstance == null) mutableCreateDelegateInstance = new CreateDelegateInstance(createDelegateInstance);
     this.resultExpression = this.myCodeMutator.Visit(mutableCreateDelegateInstance);
 }