示例#1
0
        public IMethodReference Map(IMethodSymbol methodSymbol)
        {
            Contract.Requires(methodSymbol != null);
            IMethodReference mr = null;

            if (!methodSymbolCache.TryGetValue(methodSymbol, out mr))
            {
                List <IParameterTypeInformation> ps = methodSymbol.Parameters.Length == 0 ? null : new List <IParameterTypeInformation>();
                if (methodSymbol.IsGenericMethod && methodSymbol.ConstructedFrom != methodSymbol)
                {
                    var gArgs = new List <ITypeReference>();
                    foreach (var a in methodSymbol.TypeArguments)
                    {
                        gArgs.Add(Map(a));
                    }
                    mr = new Microsoft.Cci.MutableCodeModel.GenericMethodInstanceReference()
                    {
                        CallingConvention     = methodSymbol.IsStatic ? CallingConvention.Default : CallingConvention.HasThis,
                        ContainingType        = Map(methodSymbol.ContainingType),
                        GenericArguments      = gArgs,
                        GenericMethod         = Map(methodSymbol.ConstructedFrom),
                        GenericParameterCount = (ushort)methodSymbol.TypeParameters.Length,
                        InternFactory         = this.host.InternFactory,
                        Name       = this.nameTable.GetNameFor(methodSymbol.Name),
                        Parameters = ps,
                        Type       = Map(methodSymbol.ReturnType),
                    };
                }
                else
                {
                    var m = new Microsoft.Cci.MutableCodeModel.MethodReference();
                    // 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);
                    m.CallingConvention = methodSymbol.IsStatic ? CallingConvention.Default : CallingConvention.HasThis;
                    m.ContainingType    = Map(methodSymbol.ContainingType);
                    m.InternFactory     = this.host.InternFactory;
                    m.Name       = this.nameTable.GetNameFor(methodSymbol.Name);
                    m.Parameters = ps;
                    m.Type       = Map(methodSymbol.ReturnType);
                    mr           = m;
                }
                foreach (var p in methodSymbol.Parameters)
                {
                    var p_prime = new ParameterTypeInformation()
                    {
                        ContainingSignature = mr,
                        Index = (ushort)p.Ordinal,
                        Type  = Map(p.Type),
                    };
                    ps.Add(p_prime);
                }
            }
            return(mr);
        }
示例#2
0
        public override void RewriteChildren(RootUnitNamespace rootUnitNamespace)
        {
            this.classHoldingThreeArgVersions = this.GetContractClass(rootUnitNamespace);

            base.RewriteChildren(rootUnitNamespace);

            #region Possibly add class for any contract methods that were defined.
            if (0 < this.threeArgumentVersionofContractMethod.Count)
            {
                // Only add class to assembly if any 3 arg versions were actually created
                rootUnitNamespace.Members.Add(classHoldingThreeArgVersions);
                this.allTypes.Add(classHoldingThreeArgVersions);
            }
            #endregion Possibly add class for any contract methods that were defined.

            #region Create a reference to [ContractReferenceAssembly] to mark the assembly with
            INamespaceTypeDefinition contractReferenceAssemblyAttribute = null;
            #region First see if we can find it in the same assembly as the one we are rewriting
            var unit = rootUnitNamespace.Unit;
            contractReferenceAssemblyAttribute = UnitHelper.FindType(this.host.NameTable, unit, "System.Diagnostics.Contracts.ContractReferenceAssemblyAttribute")
                                                 as INamespaceTypeDefinition;
            #endregion First see if we can find it in the same assembly as the one we are rewriting
            #region If it doesn't exist there, then define it in the same place that the three-argument versions are defined
            if (contractReferenceAssemblyAttribute is Dummy)
            {
                contractReferenceAssemblyAttribute = CreateContractReferenceAssemblyAttribute(rootUnitNamespace);
            }
            #endregion If it doesn't exist there, then define it in the same place that the three-argument versions are defined
            #region Create a reference to the ctor
            var ctorRef = new Microsoft.Cci.MutableCodeModel.MethodReference()
            {
                CallingConvention = CallingConvention.HasThis,
                ContainingType    = contractReferenceAssemblyAttribute,
                InternFactory     = this.host.InternFactory,
                Name = host.NameTable.Ctor,
                Type = systemVoidType,
            };
            var rm = ctorRef.ResolvedMethod;
            this.ContractReferenceAssemblyAttributeInstance = new CustomAttribute()
            {
                Constructor = ctorRef,
            };
            #endregion Create a reference to the ctor
            #endregion Create a reference to [ContractReferenceAssembly] to mark the assembly with

            return;
        }
示例#3
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);
        }
        public override void TraverseChildren(IMethodCall methodCall)
        {
            if (methodCall.MethodToCall.ResolvedMethod.IsSpecialName && methodCall.MethodToCall.Name.Value == "add_BackKeyPress")
            {
                // check if it is a back key handler and if it is...
                // NAVIGATION TODO this only catches really locally delegate expressions. If it is created before, we see it as a BoundExpression
                // NAVIGATION TODO and need (again) data flow analysis
                bool delegateIsIdentified = false;
                bool delegateIsAnonymous  = false;
                PhoneCodeHelper.instance().OnBackKeyPressOverriden = true;
                IBlockStatement   delegateBody      = null;
                IMethodDefinition delegateMethodRef = null;
                if (methodCall.Arguments.Count() == 1)
                {
                    IExpression             delegateArg   = methodCall.Arguments.First();
                    ICreateDelegateInstance localDelegate = delegateArg as ICreateDelegateInstance;
                    if (localDelegate != null)
                    {
                        delegateIsIdentified = true;
                        delegateMethodRef    = localDelegate.MethodToCallViaDelegate.ResolvedMethod;
                        SourceMethodBody body = delegateMethodRef.Body as SourceMethodBody;
                        if (body != null)
                        {
                            delegateBody = body.Block;
                        }

                        PhoneCodeHelper.instance().KnownBackKeyHandlers.Add(delegateMethodRef);
                    }

                    AnonymousDelegate anonDelegate = delegateArg as AnonymousDelegate;
                    if (anonDelegate != null)
                    {
                        delegateIsIdentified = true;
                        delegateIsAnonymous  = true;
                        delegateBody         = anonDelegate.Body;
                    }

                    // NAVIGATION TODO what if it has no body?
                    if (delegateBody != null)
                    {
                        bool navigates = false, cancelsNav = false;
                        ICollection <string> navTargets;
                        parseBlockForNavigation(delegateBody, out navigates, out navTargets);
                        if (navigates)
                        {
                            ICollection <Tuple <IMethodReference, string> > targets = null;
                            if (!PhoneCodeHelper.instance().BackKeyNavigatingOffenders.TryGetValue(typeBeingTraversed, out targets))
                            {
                                targets = new HashSet <Tuple <IMethodReference, string> >();
                            }

                            foreach (string tgt in navTargets)
                            {
                                IMethodReference dummyRef = null;
                                if (delegateIsAnonymous)
                                {
                                    dummyRef = new Microsoft.Cci.MutableCodeModel.MethodReference();
                                    (dummyRef as Microsoft.Cci.MutableCodeModel.MethodReference).ContainingType = typeBeingTraversed;
                                    (dummyRef as Microsoft.Cci.MutableCodeModel.MethodReference).Name           = Dummy.Name;
                                }
                                targets.Add(Tuple.Create <IMethodReference, string>((delegateIsAnonymous ? dummyRef : delegateMethodRef), "\"" + tgt + "\""));
                            }

                            PhoneCodeHelper.instance().BackKeyNavigatingOffenders[typeBeingTraversed] = targets;
                        }

                        parseBlockForEventCancellation(delegateBody, out cancelsNav);
                        if (cancelsNav)
                        {
                            string reason = "(via delegate ";
                            if (delegateIsIdentified)
                            {
                                reason += delegateMethodRef.ContainingType.ToString() + "." + delegateMethodRef.Name.Value;
                            }
                            else
                            {
                                reason += "anonymous";
                            }
                            reason += ")";
                            PhoneCodeHelper.instance().BackKeyCancellingOffenders.Add(Tuple.Create <ITypeReference, string>(typeBeingTraversed, reason));
                        }
                    }
                }

                if (!delegateIsIdentified)
                {
                    PhoneCodeHelper.instance().BackKeyHandlerOverridenByUnknownDelegate = true;
                    PhoneCodeHelper.instance().BackKeyUnknownDelegateOffenders.Add(typeBeingTraversed);
                }
            }
            base.TraverseChildren(methodCall);
        }
    /// <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;

    }
 public IMethodReference Map(R.IMethodSymbol methodSymbol) {
   Contract.Requires(methodSymbol != null);
   IMethodReference mr = null;
   if (!methodSymbolCache.TryGetValue(methodSymbol, out mr)) {
     List<IParameterTypeInformation> ps = methodSymbol.Parameters.Count == 0 ? null : new List<IParameterTypeInformation>();
     if (methodSymbol.IsGenericMethod && methodSymbol.ConstructedFrom != methodSymbol) {
       var gArgs = new List<ITypeReference>();
       foreach (var a in methodSymbol.TypeArguments){
         gArgs.Add(Map(a));
       }
       mr = new Microsoft.Cci.MutableCodeModel.GenericMethodInstanceReference() {
         CallingConvention = methodSymbol.IsStatic ? CallingConvention.Default : CallingConvention.HasThis,
         ContainingType = Map(methodSymbol.ContainingType),
         GenericArguments = gArgs,
         GenericMethod = Map(methodSymbol.ConstructedFrom),
         GenericParameterCount = (ushort) methodSymbol.TypeParameters.Count,
         InternFactory = this.host.InternFactory,
         Name = this.nameTable.GetNameFor(methodSymbol.Name),
         Parameters = ps,
         Type = Map(methodSymbol.ReturnType),
       };
     } else {
       var m = new Microsoft.Cci.MutableCodeModel.MethodReference();
       // 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);
       m.CallingConvention = methodSymbol.IsStatic ? CallingConvention.Default : CallingConvention.HasThis;
       m.ContainingType = Map(methodSymbol.ContainingType);
       m.InternFactory = this.host.InternFactory;
       m.Name = this.nameTable.GetNameFor(methodSymbol.Name);
       m.Parameters = ps;
       m.Type = Map(methodSymbol.ReturnType);
       mr = m;
     }
     foreach (var p in methodSymbol.Parameters) {
       var p_prime = new ParameterTypeInformation() {
         ContainingSignature = mr,
         Index = (ushort)p.Ordinal,
         Type = Map(p.Type),
       };
       ps.Add(p_prime);
     }
   }
   return mr;
 }
    public override void TraverseChildren(IMethodCall methodCall) {
      if (methodCall.MethodToCall.ResolvedMethod.IsSpecialName && methodCall.MethodToCall.Name.Value == "add_BackKeyPress") {
        // check if it is a back key handler and if it is...
        // NAVIGATION TODO this only catches really locally delegate expressions. If it is created before, we see it as a BoundExpression
        // NAVIGATION TODO and need (again) data flow analysis
        bool delegateIsIdentified= false;
        bool delegateIsAnonymous = false;
        PhoneCodeHelper.instance().OnBackKeyPressOverriden = true;
        IBlockStatement delegateBody = null;
        IMethodDefinition delegateMethodRef= null;
        if (methodCall.Arguments.Count() == 1) {
          IExpression delegateArg= methodCall.Arguments.First();
          ICreateDelegateInstance localDelegate = delegateArg as ICreateDelegateInstance;
          if (localDelegate != null) {
            delegateIsIdentified = true;
            delegateMethodRef = localDelegate.MethodToCallViaDelegate.ResolvedMethod;
            SourceMethodBody body= delegateMethodRef.Body as SourceMethodBody;
            if (body != null)
              delegateBody = body.Block;

            PhoneCodeHelper.instance().KnownBackKeyHandlers.Add(delegateMethodRef);
          }

          AnonymousDelegate anonDelegate = delegateArg as AnonymousDelegate;
          if (anonDelegate != null) {
            delegateIsIdentified = true;
            delegateIsAnonymous = true;
            delegateBody = anonDelegate.Body;
          }

          // NAVIGATION TODO what if it has no body?
          if (delegateBody != null) {
            bool navigates= false, cancelsNav= false;
            ICollection<string> navTargets;
            parseBlockForNavigation(delegateBody, out navigates, out navTargets);
            if (navigates) {
              ICollection<Tuple<IMethodReference,string>> targets = null;
              if (!PhoneCodeHelper.instance().BackKeyNavigatingOffenders.TryGetValue(typeBeingTraversed, out targets)) {
                targets = new HashSet<Tuple<IMethodReference,string>>();
              }

              foreach (string tgt in navTargets) {
                IMethodReference dummyRef=null;
                if (delegateIsAnonymous) {
                  dummyRef = new Microsoft.Cci.MutableCodeModel.MethodReference();
                  (dummyRef as Microsoft.Cci.MutableCodeModel.MethodReference).ContainingType= typeBeingTraversed;
                  (dummyRef as Microsoft.Cci.MutableCodeModel.MethodReference).Name = Dummy.Name;
                }
                targets.Add(Tuple.Create<IMethodReference, string>((delegateIsAnonymous ? dummyRef : delegateMethodRef), "\"" + tgt + "\""));
              }

              PhoneCodeHelper.instance().BackKeyNavigatingOffenders[typeBeingTraversed] = targets;
            }

            parseBlockForEventCancellation(delegateBody, out cancelsNav);
            if (cancelsNav) {
              string reason= "(via delegate ";
              if (delegateIsIdentified)
                reason += delegateMethodRef.ContainingType.ToString() + "." + delegateMethodRef.Name.Value;
              else
                reason += "anonymous";
              reason += ")";
              PhoneCodeHelper.instance().BackKeyCancellingOffenders.Add(Tuple.Create<ITypeReference,string>(typeBeingTraversed, reason));
            }
          }
        }

        if (!delegateIsIdentified) {
          PhoneCodeHelper.instance().BackKeyHandlerOverridenByUnknownDelegate = true;
          PhoneCodeHelper.instance().BackKeyUnknownDelegateOffenders.Add(typeBeingTraversed);
        }
      }
      base.TraverseChildren(methodCall);
    }
        private static IMethodDefinition CreateDLMethod(IMetadataHost host, ITypeDefinition typeDef, IName name, List <IParameterDefinition> parameters, ITypeReference returnType, IMethodReference getOperatingSystem, IMethodReference linuxHelpers, IMethodReference darwinHelpers, IMethodReference bsdHelpers, bool generateSecondLoad = true)
        {
            var methodDefinition = new MethodDefinition
            {
                Name       = name,
                Parameters = parameters,
                ContainingTypeDefinition = typeDef,
                IsStatic            = true,
                IsHiddenBySignature = true,
                Visibility          = TypeMemberVisibility.Public,
                Type = returnType
            };

            var labels = new ILGeneratorLabel[4];

            var linuxLabel   = new ILGeneratorLabel();
            var darwinLabel  = new ILGeneratorLabel();
            var bsdLabel     = new ILGeneratorLabel();
            var unknownLabel = new ILGeneratorLabel();

            labels[0] = linuxLabel;
            labels[1] = darwinLabel;
            labels[2] = bsdLabel;
            labels[3] = bsdLabel;

            var ilGenerator = new ILGenerator(host, methodDefinition);

            ilGenerator.Emit(OperationCode.Call, getOperatingSystem);
            ilGenerator.Emit(OperationCode.Stloc_0);
            ilGenerator.Emit(OperationCode.Ldloc_0);
            ilGenerator.Emit(OperationCode.Ldc_I4_1);
            ilGenerator.Emit(OperationCode.Sub);
            ilGenerator.Emit(OperationCode.Switch, labels);
            ilGenerator.Emit(OperationCode.Br_S, unknownLabel);

            AddOperatingSystemCase2(ilGenerator, linuxHelpers, linuxLabel, generateSecondLoad);
            AddOperatingSystemCase2(ilGenerator, darwinHelpers, darwinLabel, generateSecondLoad);
            AddOperatingSystemCase2(ilGenerator, bsdHelpers, bsdLabel, generateSecondLoad);

            ilGenerator.MarkLabel(unknownLabel);
            ilGenerator.Emit(OperationCode.Ldstr, "Platform Not Supported");

            var exceptionCtor = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name              = host.NameTable.GetNameFor(".ctor"),
                ContainingType    = host.PlatformType.SystemException,
                Type              = host.PlatformType.SystemVoid,
                CallingConvention = CallingConvention.HasThis,
                Parameters        = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Index = 0, Type = host.PlatformType.SystemString
                    }
                }
            };

            ilGenerator.Emit(OperationCode.Newobj, exceptionCtor);
            ilGenerator.Emit(OperationCode.Throw);

            methodDefinition.Body = new ILGeneratorMethodBody(ilGenerator, true, 2, methodDefinition, new List <ILocalDefinition> {
                new LocalDefinition {
                    Type = host.PlatformType.SystemInt32
                }
            }, new List <ITypeDefinition>());
            return(methodDefinition);
        }
示例#9
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);
        }
示例#10
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;

    }
        public BlockStatement GetMethodBody(IMethodDefinition cciMethod, BaseMethodDeclarationSyntax roslynMethod, bool extractContracts)
        {
            Contract.Requires(roslynMethod.Body != null);
            var expressionVisitor = new ExpressionVisitor(this.host, this.semanticModel, this.mapper, cciMethod);
            var sv = new StatementVisitor(this.host, this.semanticModel, this.mapper, cciMethod, expressionVisitor);


            var block = roslynMethod.Body;

            var statements = new List <IStatement>();

            if (roslynMethod.Kind == SyntaxKind.ConstructorDeclaration)
            {
                var            roslynCtor = roslynMethod as ConstructorDeclarationSyntax;
                var            es         = new List <IExpression>();
                var            ps         = new List <IParameterTypeInformation>();
                ITypeReference ctorClass  = null;

                if (roslynCtor.Initializer != null)
                {
                    switch (roslynCtor.Initializer.ThisOrBaseKeyword.Kind)
                    {
                    case SyntaxKind.BaseKeyword:
                        ctorClass = cciMethod.ContainingTypeDefinition.BaseClasses.First(); // safe to assume there is always at least one? what if there are more than one?
                        break;

                    case SyntaxKind.ThisKeyword:
                        ctorClass = cciMethod.ContainingType;
                        break;

                    default:
                        var msg = String.Format("Was unable to convert {0} which was used for a base/this ctor call in {1}",
                                                roslynCtor.Initializer.ThisOrBaseKeyword, MemberHelper.GetMethodSignature(cciMethod));
                        throw new ConverterException(msg);
                    }
                    foreach (var a in roslynCtor.Initializer.ArgumentList.Arguments)
                    {
                        var e = expressionVisitor.Visit(a);
                        es.Add(e);
                    }
                }
                else
                {
                    // Create a call to the nullary base constructor
                    ctorClass = cciMethod.ContainingTypeDefinition.BaseClasses.First(); // safe to assume there is always at least one? what if there are more than one?
                }
                var thisRef = new ThisReference()
                {
                    Type = cciMethod.ContainingType,
                };
                var ctorRef = new Microsoft.Cci.MutableCodeModel.MethodReference()
                {
                    CallingConvention     = CallingConvention.HasThis,
                    ContainingType        = ctorClass,
                    GenericParameterCount = 0,
                    InternFactory         = this.host.InternFactory,
                    Name       = nameTable.Ctor,
                    Parameters = ps,
                    Type       = this.host.PlatformType.SystemVoid,
                };
                statements.Add(
                    new ExpressionStatement()
                {
                    Expression = new MethodCall()
                    {
                        MethodToCall = ctorRef,
                        IsStaticCall = false,
                        ThisArgument = thisRef,
                        Type         = this.host.PlatformType.SystemVoid,
                        Arguments    = es,
                    }
                }
                    );
            }

            statements.Add(
                new EmptyStatement()
            {
                Locations = Helper.SourceLocation(this.semanticModel.SyntaxTree, block.OpenBraceToken),
            }
                );

            foreach (var s in block.Statements)
            {
                var s_prime = sv.Visit(s);
                statements.Add(s_prime);
            }

            // REVIEW: need to do this only if debugging info is needed?
            // (But if it isn't done, then there can be unreachable nops
            // corresponding to close curlys for blocks because of return
            // statements within the block. When that happens at the method
            // level, then peverify is unhappy with the assembly.)
            //if (false) {
            //  // commented this out because it is needed only if this is being used
            //  // to generate IL that in the end should pass peverify (and run).
            //  statements = CreateUnifiedReturnPoint(statements, cciMethod.Type);
            //}

            BlockStatement bs = new BlockStatement()
            {
                Statements = statements,
            };

            return(bs);
        }
示例#12
0
        private static IMethodDefinition CreateIsLibraryInitialized(IMetadataHost host, ITypeDefinition typeDef, IFieldReference intPtrZero)
        {
            MethodDefinition methodDefinition = new MethodDefinition
            {
                ContainingTypeDefinition = typeDef,
                IsStatic            = true,
                IsNeverInlined      = true,
                IsHiddenBySignature = true,
                Visibility          = TypeMemberVisibility.Assembly,
                Type       = host.PlatformType.SystemVoid,
                Parameters = new List <IParameterDefinition> {
                    new ParameterDefinition {
                        Index = 0, Type = host.PlatformType.SystemIntPtr
                    }, new ParameterDefinition {
                        Index = 1, Type = host.PlatformType.SystemString
                    }
                },
                Name = host.NameTable.GetNameFor("IsLibraryInitialized")
            };

            var ilGenerator = new ILGenerator(host, methodDefinition);
            var retLabel    = new ILGeneratorLabel();

            var exceptionCtor = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name              = host.NameTable.GetNameFor(".ctor"),
                ContainingType    = host.PlatformType.SystemException,
                Type              = host.PlatformType.SystemVoid,
                CallingConvention = CallingConvention.HasThis,
                Parameters        = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Index = 0, Type = host.PlatformType.SystemString
                    }
                }
            };

            var stringConcat = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.GetNameFor("Concat"),
                ContainingType = host.PlatformType.SystemString,
                Type           = host.PlatformType.SystemString,
                Parameters     = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Index = 0, Type = host.PlatformType.SystemString
                    }, new ParameterDefinition {
                        Index = 1, Type = host.PlatformType.SystemString
                    }, new ParameterDefinition {
                        Index = 2, Type = host.PlatformType.SystemString
                    }, new ParameterDefinition {
                        Index = 3, Type = host.PlatformType.SystemString
                    }
                }
            };

            var intPtrOpEquality = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.OpEquality,
                ContainingType = host.PlatformType.SystemIntPtr,
                Type           = host.PlatformType.SystemBoolean,
                Parameters     = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Index = 0, Type = host.PlatformType.SystemIntPtr
                    }, new ParameterDefinition {
                        Index = 1, Type = host.PlatformType.SystemIntPtr
                    }
                }
            };

            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldsfld, intPtrZero);
            ilGenerator.Emit(OperationCode.Call, intPtrOpEquality);
            ilGenerator.Emit(OperationCode.Brfalse_S, retLabel);
            ilGenerator.Emit(OperationCode.Ldstr, "Library '");
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Ldstr, "' is not initialized. Load the native library (from its file path) by calling LoadLibrary");
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Call, stringConcat);
            ilGenerator.Emit(OperationCode.Newobj, exceptionCtor);
            ilGenerator.Emit(OperationCode.Throw);
            ilGenerator.MarkLabel(retLabel);
            ilGenerator.Emit(OperationCode.Ret);

            methodDefinition.Body = new ILGeneratorMethodBody(ilGenerator, true, 8, methodDefinition, new List <ILocalDefinition>(), new List <ITypeDefinition>());

            return(methodDefinition);
        }
示例#13
0
        private static IMethodDefinition CreateGetProcAddress(IMetadataHost host, ITypeDefinition typeDef, IMethodReference windowsGetProcAddress, IMethodReference unixGetProcAddress, IFieldReference isUnix, IFieldReference intPtrZero)
        {
            var methodDefinition = new MethodDefinition
            {
                Name = host.NameTable.GetNameFor("GetProcAddress"),
                ContainingTypeDefinition = typeDef,
                Parameters = new List <IParameterDefinition>
                {
                    new ParameterDefinition {
                        Index = 0, Type = host.PlatformType.SystemIntPtr
                    },
                    new ParameterDefinition {
                        Index = 1, Type = host.PlatformType.SystemString
                    }
                },
                IsStatic            = true,
                IsHiddenBySignature = true,
                Visibility          = TypeMemberVisibility.Public,
                Type = host.PlatformType.SystemIntPtr
            };

            var ilGenerator = new ILGenerator(host, methodDefinition);

            var label    = new ILGeneratorLabel();
            var retLabel = new ILGeneratorLabel();
            var dupLabel = new ILGeneratorLabel();

            var exceptionCtor = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name              = host.NameTable.GetNameFor(".ctor"),
                ContainingType    = host.PlatformType.SystemException,
                Type              = host.PlatformType.SystemVoid,
                CallingConvention = CallingConvention.HasThis,
                Parameters        = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Index = 0, Type = host.PlatformType.SystemString
                    }
                }
            };

            var stringConcat = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.GetNameFor("Concat"),
                ContainingType = host.PlatformType.SystemString,
                Type           = host.PlatformType.SystemString,
                Parameters     = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Index = 0, Type = host.PlatformType.SystemString
                    }, new ParameterDefinition {
                        Index = 1, Type = host.PlatformType.SystemString
                    }
                }
            };

            var intPtrOpEquality = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.OpEquality,
                ContainingType = host.PlatformType.SystemIntPtr,
                Type           = host.PlatformType.SystemBoolean,
                Parameters     = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Index = 0, Type = host.PlatformType.SystemIntPtr
                    }, new ParameterDefinition {
                        Index = 1, Type = host.PlatformType.SystemIntPtr
                    }
                }
            };

            ilGenerator.Emit(OperationCode.Ldsfld, isUnix);
            ilGenerator.Emit(OperationCode.Brtrue_S, label);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Call, windowsGetProcAddress);
            ilGenerator.Emit(OperationCode.Br_S, dupLabel);
            ilGenerator.MarkLabel(label);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Call, unixGetProcAddress);
            ilGenerator.MarkLabel(dupLabel);
            ilGenerator.Emit(OperationCode.Dup);
            ilGenerator.Emit(OperationCode.Ldsfld, intPtrZero);
            ilGenerator.Emit(OperationCode.Call, intPtrOpEquality);
            ilGenerator.Emit(OperationCode.Brfalse_S, retLabel);
            ilGenerator.Emit(OperationCode.Ldstr, "GetProcAddress failed for: ");
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Call, stringConcat);
            ilGenerator.Emit(OperationCode.Newobj, exceptionCtor);
            ilGenerator.Emit(OperationCode.Throw);
            ilGenerator.MarkLabel(retLabel);
            ilGenerator.Emit(OperationCode.Ret);

            methodDefinition.Body = new ILGeneratorMethodBody(ilGenerator, true, 8, methodDefinition, new List <ILocalDefinition>(), new List <ITypeDefinition>());

            return(methodDefinition);
        }
示例#14
0
        public InteropHelperReferences(IMetadataHost host, Assembly assembly)
        {
            ITypeReference systemEnvironment = null;

            foreach (var typeRef in assembly.ResolvedAssembly.GetTypeReferences())
            {
                var name = TypeHelper.GetTypeName(typeRef);

                if (string.Equals(name, "System.Environment", StringComparison.Ordinal))
                {
                    systemEnvironment = typeRef;
                    continue;
                }

                if (string.Equals(name, "System.Runtime.InteropServices.Marshal", StringComparison.Ordinal))
                {
                    this.SystemRuntimeInteropServicesMarshal = typeRef;
                }

                if (string.Equals(name, "System.Runtime.CompilerServices.RuntimeHelpers", StringComparison.Ordinal))
                {
                    this.SystemRuntimeCompilerServicesRuntimeHelpers = typeRef;
                }
            }

            var mscorlibAsmRef = assembly.AssemblyReferences.FirstOrDefault(t => t.Name.Value.Equals("mscorlib"));

            if (mscorlibAsmRef == null)
            {
                var tempRef = new AssemblyReference
                {
                    Name           = host.NameTable.GetNameFor("mscorlib"),
                    Version        = new Version(4, 0, 0, 0),
                    PublicKeyToken = new List <byte> {
                        0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89
                    }
                };

                mscorlibAsmRef = tempRef;
                assembly.AssemblyReferences.Add(mscorlibAsmRef);
            }

            if (systemEnvironment == null)
            {
                systemEnvironment = CreateTypeReference(host, mscorlibAsmRef, "System.Environment");
            }

            if (this.SystemRuntimeInteropServicesMarshal == null)
            {
                var interopServicesAssembly = assembly.AssemblyReferences.FirstOrDefault(t => t.Name.Value.Equals("System.Runtime.InteropServices")) ?? mscorlibAsmRef;
                this.SystemRuntimeInteropServicesMarshal = CreateTypeReference(host, interopServicesAssembly, "System.Runtime.InteropServices.Marshal");
            }

            if (this.SystemRuntimeCompilerServicesRuntimeHelpers == null)
            {
                var runtimeAssembly = assembly.AssemblyReferences.FirstOrDefault(t => t.Name.Value.Equals("System.Runtime")) ?? mscorlibAsmRef;
                this.SystemRuntimeCompilerServicesRuntimeHelpers = CreateTypeReference(host, runtimeAssembly, "System.Runtime.CompilerServices.RuntimeHelpers");
            }

            var getNewLine = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.GetNameFor("get_NewLine"),
                ContainingType = systemEnvironment,
                Type           = host.PlatformType.SystemString
            };

            var stringOpEquality = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.OpEquality,
                ContainingType = host.PlatformType.SystemString,
                Type           = host.PlatformType.SystemBoolean,
                Parameters     = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Index = 0, Type = host.PlatformType.SystemString
                    }, new ParameterDefinition {
                        Index = 1, Type = host.PlatformType.SystemString
                    }
                }
            };

            var rootUnitNamespace = new RootUnitNamespace();

            rootUnitNamespace.Members.AddRange(assembly.UnitNamespaceRoot.Members);
            assembly.UnitNamespaceRoot = rootUnitNamespace;
            rootUnitNamespace.Unit     = assembly;

            var typeDef = CreatePInvokeHelpers(rootUnitNamespace, host);

            this.PInvokeHelpers = typeDef;
            rootUnitNamespace.Members.Add(typeDef);
            assembly.AllTypes.Add(typeDef);

            var platformSpecificHelpers = new PlatformSpecificHelpersTypeAdder(host, typeDef, this.SystemRuntimeInteropServicesMarshal);

            var windowsLoaderMethods = platformSpecificHelpers.WindowsLoaderMethods;
            var unixLoaderMethods    = platformSpecificHelpers.UnixLoaderMethods;

            var isUnix = CreateIsUnixField(host, typeDef);

            var isUnixStaticFunction = CreateIsUnixStaticFunction(host, typeDef, getNewLine, stringOpEquality);
            var cctor = CreateCCtor(host, typeDef, isUnix, isUnixStaticFunction);

            var intPtrZero = new FieldReference
            {
                Name           = host.NameTable.GetNameFor("Zero"),
                ContainingType = host.PlatformType.SystemIntPtr,
                Type           = host.PlatformType.SystemIntPtr
            };

            var getLength = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name              = host.NameTable.GetNameFor("get_Length"),
                ContainingType    = host.PlatformType.SystemString,
                Type              = host.PlatformType.SystemInt32,
                CallingConvention = CallingConvention.HasThis
            };

            var getChars = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name              = host.NameTable.GetNameFor("get_Chars"),
                ContainingType    = host.PlatformType.SystemString,
                Type              = host.PlatformType.SystemChar,
                CallingConvention = CallingConvention.HasThis,
                Parameters        = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Index = 0, Type = host.PlatformType.SystemInt32
                    }
                }
            };

            var stringToGlobalAnsi = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.GetNameFor("StringToHGlobalAnsi"),
                ContainingType = this.SystemRuntimeInteropServicesMarshal,
                Type           = host.PlatformType.SystemIntPtr,
                Parameters     = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Type = host.PlatformType.SystemString
                    }
                }
            };

            var stringToGlobalUni = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.GetNameFor("StringToHGlobalUni"),
                ContainingType = this.SystemRuntimeInteropServicesMarshal,
                Type           = host.PlatformType.SystemIntPtr,
                Parameters     = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Type = host.PlatformType.SystemString
                    }
                }
            };

            var intPtrOpInequality = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.OpInequality,
                ContainingType = host.PlatformType.SystemIntPtr,
                Type           = host.PlatformType.SystemBoolean,
                Parameters     = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Index = 0, Type = host.PlatformType.SystemIntPtr
                    }, new ParameterDefinition {
                        Index = 1, Type = host.PlatformType.SystemIntPtr
                    }
                }
            };

            var freeHGlobal = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.GetNameFor("FreeHGlobal"),
                ContainingType = this.SystemRuntimeInteropServicesMarshal,
                Type           = host.PlatformType.SystemVoid,
                Parameters     = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Type = host.PlatformType.SystemIntPtr
                    }
                }
            };

            this.LoadLibrary                         = CreateLoadLibrary(host, typeDef, windowsLoaderMethods.LoadLibrary, unixLoaderMethods.LoadLibrary, isUnix, intPtrZero);
            this.FreeLibrary                         = CreateFreeLibrary(host, typeDef, windowsLoaderMethods.FreeLibrary, unixLoaderMethods.FreeLibrary, isUnix);
            this.GetProcAddress                      = CreateGetProcAddress(host, typeDef, windowsLoaderMethods.GetProcAddress, unixLoaderMethods.GetProcAddress, isUnix, intPtrZero);
            this.StringToAnsiByteArray               = CreateStringToAnsi(host, typeDef, getLength, getChars);
            this.StringArrayAnsiMarshallingProlog    = CreateStringArrayMarshallingProlog(host, typeDef, stringToGlobalAnsi, "StringArrayAnsiMarshallingProlog");
            this.StringArrayUnicodeMarshallingProlog = CreateStringArrayMarshallingProlog(host, typeDef, stringToGlobalUni, "StringArrayUnicodeMarshallingProlog");
            this.StringArrayMarshallingEpilog        = CreateStringArrayMarshallingEpilog(host, typeDef, intPtrZero, intPtrOpInequality, freeHGlobal);
            this.IsLibraryInitialized                = CreateIsLibraryInitialized(host, typeDef, intPtrZero);

            typeDef.Methods = new List <IMethodDefinition> {
                isUnixStaticFunction, cctor, this.LoadLibrary, this.FreeLibrary, this.GetProcAddress, this.StringToAnsiByteArray, this.StringArrayAnsiMarshallingProlog, this.StringArrayUnicodeMarshallingProlog, this.StringArrayMarshallingEpilog, this.IsLibraryInitialized
            };
            typeDef.Fields = new List <IFieldDefinition> {
                isUnix
            };

            typeDef.Methods.AddRange(platformSpecificHelpers.Methods);
        }
示例#15
0
文件: Rewriter.cs 项目: xornand/cci
    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;
    }
示例#16
0
文件: Rewriter.cs 项目: xornand/cci
    public override void RewriteChildren(RootUnitNamespace rootUnitNamespace) {
      this.classHoldingThreeArgVersions = this.GetContractClass(rootUnitNamespace);

      base.RewriteChildren(rootUnitNamespace);

      #region Possibly add class for any contract methods that were defined.
      if (0 < this.threeArgumentVersionofContractMethod.Count) {
        // Only add class to assembly if any 3 arg versions were actually created
        rootUnitNamespace.Members.Add(classHoldingThreeArgVersions);
        this.allTypes.Add(classHoldingThreeArgVersions);
      }
      #endregion Possibly add class for any contract methods that were defined.

      #region Create a reference to [ContractReferenceAssembly] to mark the assembly with
      INamespaceTypeDefinition contractReferenceAssemblyAttribute = null;
      #region First see if we can find it in the same assembly as the one we are rewriting
      var unit = rootUnitNamespace.Unit;
      contractReferenceAssemblyAttribute = UnitHelper.FindType(this.host.NameTable, unit, "System.Diagnostics.Contracts.ContractReferenceAssemblyAttribute")
                          as INamespaceTypeDefinition;
      #endregion First see if we can find it in the same assembly as the one we are rewriting
      #region If it doesn't exist there, then define it in the same place that the three-argument versions are defined
      if (contractReferenceAssemblyAttribute is Dummy) {
        contractReferenceAssemblyAttribute = CreateContractReferenceAssemblyAttribute(rootUnitNamespace);
      }
      #endregion If it doesn't exist there, then define it in the same place that the three-argument versions are defined
      #region Create a reference to the ctor
      var ctorRef = new Microsoft.Cci.MutableCodeModel.MethodReference() {
        CallingConvention = CallingConvention.HasThis,
        ContainingType = contractReferenceAssemblyAttribute,
        InternFactory = this.host.InternFactory,
        Name = host.NameTable.Ctor,
        Type = systemVoidType,
      };
      var rm = ctorRef.ResolvedMethod;
      this.ContractReferenceAssemblyAttributeInstance = new CustomAttribute() {
        Constructor = ctorRef,
      };
      #endregion Create a reference to the ctor
      #endregion Create a reference to [ContractReferenceAssembly] to mark the assembly with

      return;
    }
示例#17
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(IMethodSymbol methodSymbol)
        {
            Contract.Requires(methodSymbol != null);
            Contract.Ensures(Contract.Result <MethodDefinition>() != null);

            var containingType = (ITypeDefinition)this.typeSymbolCache[methodSymbol.ContainingType];
            var isConstructor  = methodSymbol.MethodKind == MethodKind.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);
        }
        private static List <IMethodDefinition> CreateUnixHelpers(IMetadataHost host, ITypeDefinition typeDef, ITypeReference marshalClass, List <IMethodDefinition> linuxMethodList, List <IMethodDefinition> darwinMethodList, List <IMethodDefinition> bsdMethodList, IModuleReference libc)
        {
            var intPtrZero = new FieldReference
            {
                Name           = host.NameTable.GetNameFor("Zero"),
                ContainingType = host.PlatformType.SystemIntPtr,
                Type           = host.PlatformType.SystemIntPtr
            };

            var allocalHGlobal = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.GetNameFor("AllocHGlobal"),
                ContainingType = marshalClass,
                Type           = host.PlatformType.SystemIntPtr,
                Parameters     = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Index = 0, Type = host.PlatformType.SystemInt32
                    }
                }
            };

            var ptrToStringAnsi = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.GetNameFor("PtrToStringAnsi"),
                ContainingType = marshalClass,
                Type           = host.PlatformType.SystemString,
                Parameters     = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Index = 0, Type = host.PlatformType.SystemIntPtr
                    }
                }
            };

            var freeHGlobal = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.GetNameFor("FreeHGlobal"),
                ContainingType = marshalClass,
                Type           = host.PlatformType.SystemVoid,
                Parameters     = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Index = 0, Type = host.PlatformType.SystemIntPtr
                    }
                }
            };

            var intPtrOpInEquality = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.OpInequality,
                ContainingType = host.PlatformType.SystemIntPtr,
                Type           = host.PlatformType.SystemBoolean,
                Parameters     = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Index = 0, Type = host.PlatformType.SystemIntPtr
                    }, new ParameterDefinition {
                        Index = 1, Type = host.PlatformType.SystemIntPtr
                    }
                }
            };

            var stringOpEquality = new Microsoft.Cci.MutableCodeModel.MethodReference
            {
                Name           = host.NameTable.OpEquality,
                ContainingType = host.PlatformType.SystemString,
                Type           = host.PlatformType.SystemBoolean,
                Parameters     = new List <IParameterTypeInformation> {
                    new ParameterDefinition {
                        Index = 0, Type = host.PlatformType.SystemString
                    }, new ParameterDefinition {
                        Index = 1, Type = host.PlatformType.SystemString
                    }
                }
            };

            var unamePInvokeMethod = CreateUnamePInvokeMethod(host, typeDef, libc);
            var unameMethod        = CreateUnameMethod(host, typeDef, intPtrZero, allocalHGlobal, ptrToStringAnsi, freeHGlobal, unamePInvokeMethod, intPtrOpInEquality);
            var getosmethod        = CreateGetOperatingSystemMethod(host, typeDef, stringOpEquality, unameMethod);

            var dlopen  = CreateDLOpen(host, typeDef, getosmethod, linuxMethodList[0], darwinMethodList[0], bsdMethodList[0]);
            var dlclose = CreateDLClose(host, typeDef, getosmethod, linuxMethodList[1], darwinMethodList[1], bsdMethodList[1]);
            var dlsym   = CreateDLSym(host, typeDef, getosmethod, linuxMethodList[2], darwinMethodList[2], bsdMethodList[2]);

            return(new List <IMethodDefinition> {
                dlopen, dlclose, dlsym, unameMethod, unamePInvokeMethod, getosmethod
            });
        }
示例#19
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
   }
 }