private TypeDefinition GenerateTypeA(AssemblyDefinition assembly)
        {
            var objType = assembly.MainModule.Import(typeof (object));

            // define base class
            var aType = new TypeDefinition("A", "", TypeAttributes.Class, objType);
            assembly.MainModule.Types.Add(aType);

            var typeParameter = new GenericParameter("T", aType);
            aType.GenericParameters.Add(typeParameter);

            var baseMethod = new MethodDefinition("Get",
                                                  MethodAttributes.Assem | MethodAttributes.Virtual |
                                                  MethodAttributes.NewSlot, typeParameter);
            aType.Methods.Add(baseMethod);
            baseMethod.DeclaringType = aType;

            var local = new VariableDefinition(typeParameter);
            baseMethod.Body.Variables.Add(local);

            var cil = baseMethod.Body.CilWorker;
            cil.Emit(OpCodes.Ldloca, local);
            cil.Emit(OpCodes.Initobj, typeParameter);
            cil.Emit(OpCodes.Ldloc, local);
            cil.Emit(OpCodes.Ret);
            return aType;
        }
Example #2
0
 public SystemTypeForGenericParameterValue(GenericParameter genericParameter, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes)
 {
     Kind             = ValueNodeKind.SystemTypeForGenericParameter;
     GenericParameter = genericParameter;
     DynamicallyAccessedMemberTypes = dynamicallyAccessedMemberTypes;
     SourceContext = genericParameter;
 }
Example #3
0
            public AnalysisNet.Types.IGenericParameterReference GetGenericParameter(Cecil.GenericParameter cecilParameter)
            {
                Cecil.IGenericParameterProvider owner = cecilParameter.Owner;
                if (genericParamsMap.TryGetValue(owner, out GenericParameterMap map))
                {
                    return(map[cecilParameter.Position]);
                }

                // populates map
                if (cecilParameter.Type == Cecil.GenericParameterType.Method)
                {
                    typeExtractor.ExtractMethod(owner as Cecil.MethodReference);
                }
                else
                {
                    // check my assumption
                    if ((owner is Cecil.GenericInstanceType))
                    {
                        throw new Exception();
                    }

                    typeExtractor.ExtractType(owner as Cecil.TypeReference);
                }

                map = genericParamsMap[owner];
                return(map[cecilParameter.Position]);
            }
 /// <summary>
 /// Default ctor
 /// </summary>
 public ILGenericParameter(XModule module, GenericParameter p) : 
     base(module)
 {
     this.p = p;
     constraints = new Lazy<XTypeReference[]>(()=>
         p.Constraints.Select(k=>AsTypeReference(module, k)).ToArray());
 }
 /// <summary>
 /// Clones the specified generic parameter.
 /// </summary>
 /// <param name="genericParameter">The generic parameter.</param>
 /// <param name="methodDefinition">The method definition.</param>
 /// <returns></returns>
 public static GenericParameter Clone(this GenericParameter genericParameter, MethodDefinition methodDefinition)
 {
     var newGenericParameter = new GenericParameter(methodDefinition);
     newGenericParameter.Attributes = genericParameter.Attributes;
     newGenericParameter.Name = genericParameter.Name;
     return newGenericParameter;
 }
Example #6
0
        public static int GetIndexOfGenericParameter(MethodDefinition method, GenericParameter parameter)
        {
            if (parameter.IsGenericParameter)
            {
                // Genetic parameter has origin on method?
                for (var index = 0; index < method.GenericParameters.Count; index++)
                {
                    if (method.GenericParameters[index].MetadataToken == parameter.MetadataToken)
                    {
                        return index;
                    }
                }

                // Genetic parameter has origin on declared type?
                for (var index = 0; index < method.DeclaringType.GenericParameters.Count; index++)
                {
                    if (method.DeclaringType.GenericParameters[index].MetadataToken ==
                        parameter.MetadataToken)
                    {
                        return index;
                    }
                }
            }

            throw new InvalidOperationException("Could not find generic parameter.");
        }
Example #7
0
        /// <summary>
        /// Resolve the given generic parameter to a generic argument.
        /// </summary>
        public TypeReference Resolve(GenericParameter gp)
        {
            var owner = gp.Owner as TypeReference;
            if (owner == null)
                return gp; // Do not resolve generic method parameters for now

            // Try to resolve the owner
            var ownerDef = owner.GetElementType().Resolve();
            if (ownerDef == null)
                return gp;

            // Try to find the owner in our map
            var map = GetTypeToGit();
            GenericInstanceType git;
            if (!map.TryGetValue(ownerDef, out git))
            {
                // No mapping found
                return gp;
            }

            // Replace with the given generic argument
            var result = git.GenericArguments[gp.Position];
            var resultAsGp = result as GenericParameter;
            return (resultAsGp != null) ? Resolve(resultAsGp) : result;
        }
        public override TypeReference Visit(GenericParameter type)
        {
            TypeReference result;
            if (genericTypeMapping.TryGetValue(type, out result))
                return result;

            return base.Visit(type);
        }
 private TypeReference HandleOwnerlessInvalidILCode(GenericParameter genericParameter)
 {
     if (((genericParameter.Type == GenericParameterType.Method) && (this._typeDefinitionContext != null)) && (genericParameter.Position < this._typeDefinitionContext.GenericArguments.Count))
     {
         return this._typeDefinitionContext.GenericArguments[genericParameter.Position];
     }
     return genericParameter.Module.TypeSystem.Object;
 }
Example #10
0
 public TypeReference GetGenericParameter(GenericParameter genericParamter, IGenericParameterProvider[] paramProviders)
 {
     #if GENERIC
     IGenericParameterProvider context = GetContext(genericParamter, paramProviders);
     return context.GenericParameters[genericParamter.Position];
     #else
     return type;
     #endif
 }
	static TypeReference CreateConstraint (string @namespace, string name, GenericParameter parameter)
	{
		return new TypeReference (
			@namespace,
			name,
			parameter.Module,
			parameter.Module.AssemblyReferences.First<AssemblyNameReference> (a => a.Name == "mscorlib"),
			false);
	}
Example #12
0
		static void AddConstraintsFromType(ITypeParameter tp, GenericParameter g)
		{
			foreach (TypeReference constraint in g.Constraints) {
				if (tp.Method != null) {
					tp.Constraints.Add(CreateType(tp.Class.ProjectContent, tp.Method, constraint));
				} else {
					tp.Constraints.Add(CreateType(tp.Class.ProjectContent, tp.Class, constraint));
				}
			}
		}
    private List<GenericConstraint> CreateGenericConstraints(GenericParameter genericParameter)
    {
      List<GenericConstraint> result = null;

      if ((genericParameter.Attributes & GenericParameterAttributes.ReferenceTypeConstraint) == GenericParameterAttributes.ReferenceTypeConstraint)
      {
        result = new List<GenericConstraint>();

        result.Add(new BuiltInGenericConstraint(BuiltInGenericConstraintsTypes.Class));
      }
      else if ((genericParameter.Attributes & GenericParameterAttributes.NotNullableValueTypeConstraint) == GenericParameterAttributes.NotNullableValueTypeConstraint)
      {
        result = new List<GenericConstraint>();

        result.Add(new BuiltInGenericConstraint(BuiltInGenericConstraintsTypes.Struct));
      }

      ConstraintCollection baseOrInterfaceConstraints = genericParameter.Constraints;

      if (baseOrInterfaceConstraints != null)
      {
        if (result == null) { result = new List<GenericConstraint>(); }

        for (int i = 0; i < baseOrInterfaceConstraints.Count; i++)
        {
          TypeReference baseTypeOrInterface = baseOrInterfaceConstraints[i];

          if (baseTypeOrInterface.FullName == "System.ValueType")
          {
            continue;
          }

          if (Utils.IsGenericParameter(baseTypeOrInterface))
          {
            result.Add(new NakedTypeConstraint(baseTypeOrInterface.Name));
          }
          else
          {
            string[] readableForms = Tools.GetHumanReadableForms(baseTypeOrInterface);

            result.Add(new TypeGenericConstraint(readableForms[0]));
          }
        }
      }

      if ((genericParameter.Attributes & GenericParameterAttributes.DefaultConstructorConstraint) == GenericParameterAttributes.DefaultConstructorConstraint
       && (genericParameter.Attributes & GenericParameterAttributes.NotNullableValueTypeConstraint) == 0)
      {
        if (result == null) { result = new List<GenericConstraint>(); }

        result.Add(new BuiltInGenericConstraint(BuiltInGenericConstraintsTypes.New));
      }

      return result;
    }
Example #14
0
 public static bool GenericParameterEquals(GenericParameter genericParameter, GenericParameter genericParameter2)
 {
     if (genericParameter.Position != genericParameter.Position)
     {
         return false;
     }
     if (!TypeReferenceEquals(genericParameter, genericParameter2, false))
     {
         return false;
     }
     return true; // TODO: Implement this properly
 }
 private static void CloneGenericParameterProperties(GenericParameter genericParameter,
     GenericParameter newGenericParameter)
 {
     newGenericParameter.Attributes = genericParameter.Attributes;
     genericParameter.Constraints.ForEach(gp => newGenericParameter.Constraints.Add(gp));
     genericParameter.CustomAttributes.ForEach(ca => newGenericParameter.CustomAttributes.Add(ca));
     newGenericParameter.DeclaringType = genericParameter.DeclaringType;
     genericParameter.GenericParameters.ForEach(gp => newGenericParameter.GenericParameters.Add(gp));
     newGenericParameter.HasDefaultConstructorConstraint = genericParameter.HasDefaultConstructorConstraint;
     newGenericParameter.IsContravariant = genericParameter.IsContravariant;
     newGenericParameter.IsCovariant = genericParameter.IsCovariant;
     newGenericParameter.IsNonVariant = genericParameter.IsNonVariant;
 }
Example #16
0
            private AnalysisNet.Types.GenericParameterKind GetKind(Cecil.GenericParameter cecilContainer)
            {
                if (cecilContainer.Type == Cecil.GenericParameterType.Type)
                {
                    return(AnalysisNet.Types.GenericParameterKind.Type);
                }
                else if (cecilContainer.Type == Cecil.GenericParameterType.Method)
                {
                    return(AnalysisNet.Types.GenericParameterKind.Method);
                }

                throw new NotImplementedException();
            }
Example #17
0
        private AnalysisNet.Types.TypeKind GetGenericParameterTypeKind(Cecil.GenericParameter parameterdef)
        {
            AnalysisNet.Types.TypeKind result;
            if (parameterdef.IsValueType)
            {
                result = AnalysisNet.Types.TypeKind.ValueType;
            }
            else
            {
                result = AnalysisNet.Types.TypeKind.ReferenceType;
            }

            return(result);
        }
        internal static GenericParameterVariance GetVariance(this GenericParameter genericParameter)
        {
            if (genericParameter.IsCovariant)
            {
                return(GenericParameterVariance.Covariant);
            }

            if (genericParameter.IsContravariant)
            {
                return(GenericParameterVariance.Contravariant);
            }

            return(GenericParameterVariance.NonVariant);
        }
 TypeReference GetEnumType(CustomAttribute attribute, GenericParameter parameter)
 {
     if (attribute.HasConstructorArguments)
     {
         var typeReference = (TypeReference) attribute.ConstructorArguments[0].Value;
         if (!typeReference.IsEnumType())
         {
             var message = $"The type '{typeReference.FullName}' is not an enum type. Only enum types are permitted in an EnumConstraintAttribute.";
             throw new WeavingException(message);
         }
         return typeReference;
     }
     return CreateConstraint("System", "Enum", parameter);
 }
Example #20
0
        private void ExtractGenericTypeParameters(AnalysisNet.Types.IGenericDefinition definingType, Cecil.TypeDefinition typedef)
        {
            for (int i = 0; i < typedef.GenericParameters.Count; ++i)
            {
                Cecil.GenericParameter parameterdef = typedef.GenericParameters[i];
                ushort index = (ushort)i;
                string name  = parameterdef.Name;
                AnalysisNet.Types.TypeKind         typeKind  = GetGenericParameterTypeKind(parameterdef);
                AnalysisNet.Types.GenericParameter parameter = new AnalysisNet.Types.GenericParameter(AnalysisNet.Types.GenericParameterKind.Type, index, name, typeKind);

                ExtractCustomAttributes(parameter.Attributes, parameterdef.CustomAttributes);

                parameter.GenericContainer = definingType;
                definingType.GenericParameters.Add(parameter);

                parameter.Constraints.AddRange(parameterdef.Constraints.Select(c => ExtractType(c.ConstraintType)));
            }
        }
Example #21
0
            public void MapGenericParameters(Cecil.IGenericParameterProvider cecilContainer, AnalysisNet.Types.IGenericReference analysisNetContainer)
            {
                GenericParameterMap map = new GenericParameterMap();

                for (int i = 0; i < cecilContainer.GenericParameters.Count; i++)
                {
                    Cecil.GenericParameter cecilParam = cecilContainer.GenericParameters.ElementAt(i);
                    AnalysisNet.Types.GenericParameterReference analysisNetParam = new AnalysisNet.Types.GenericParameterReference(GetKind(cecilParam), (ushort)cecilParam.Position)
                    {
                        GenericContainer = analysisNetContainer
                    };
                    map[i] = analysisNetParam;
                }

                genericParamsMap[cecilContainer] = map;

                //throw new NotImplementedException();
            }
Example #22
0
        private static string CollectConstraints(GenericParameter param)
        {
            List<string> constraints = new List<string>();

            if (param.HasDefaultConstructorConstraint)
            {
                constraints.Add("new()");
            }

            if(param.HasReferenceTypeConstraint)
            {
                constraints.Add("class");
            }

            constraints.AddRange(param.Constraints.Select(constraint => constraint.ToString()));

            return string.Join(", ", constraints.ToArray());
        }
        public static void InjectGenericParameter(this IGenericParameterProvider owner, GenericParameter parameter, ReferenceResolver resolver)
        {
            GenericParameter newParameter = new GenericParameter(parameter.Name, owner)
            {
                Attributes = parameter.Attributes
            };

            owner.GenericParameters.Add(newParameter);

            MetadataBuilderHelper.CopyCustomAttributes(newParameter, parameter, resolver);

            foreach (var constraint in parameter.Constraints)
            {
                if (owner is MethodReference)
                    newParameter.Constraints.Add(resolver.ReferenceType(constraint, owner, ((MethodReference)owner).DeclaringType));
                else
                    newParameter.Constraints.Add(resolver.ReferenceType(constraint, owner));
            }
        }
	static void Process (GenericParameter parameter)
	{
		if (!parameter.HasCustomAttributes)
			return;

		var attributes = parameter.CustomAttributes;
		for (int i = 0; i < attributes.Count; i++) {
			var attribute = attributes [i];
			if (IsDelegateConstraintAttribute (attribute)) {
				parameter.Attributes = GenericParameterAttributes.NonVariant;
				parameter.Constraints.Clear ();
				parameter.Constraints.Add (CreateConstraint ("System", "Delegate", parameter));
				attributes.RemoveAt (i--);
			} else if (IsEnumConstraintAttribute (attribute)) {
				parameter.Attributes = GenericParameterAttributes.NonVariant;
				parameter.Constraints.Clear ();
				parameter.Constraints.Add (CreateConstraint ("System", "Enum", parameter));
				attributes.RemoveAt (i--);
			}
		}
	}
        public MethodReference GetCallableObjectFactoryCreateMethod(AssemblyDefinition assemblyDef, ModuleDefinition moduleDefinition, TypeReference instantiatedType, IAssemblyTracker tracker)
        {
            var tempRef = GetOrCreateRemotionInterfacesReference (assemblyDef, moduleDefinition, tracker);

              var objectFactoryReference = new TypeReference (_objectFactoryNamespace, _objectFactoryName, moduleDefinition, tempRef);
              var paramListReference = new TypeReference (_paramListNamespace, _paramListName, moduleDefinition, tempRef);

              var createReference = new MethodReference ("Create", moduleDefinition.TypeSystem.Void, objectFactoryReference);
              var createTypeParam = new GenericParameter ("T", createReference);

              createReference.GenericParameters.Add (createTypeParam);
              createReference.ReturnType = createTypeParam;
              createReference.Parameters.Add (new ParameterDefinition (moduleDefinition.TypeSystem.Boolean));
              createReference.Parameters.Add (new ParameterDefinition (paramListReference));
              createReference.Parameters.Add (new ParameterDefinition (new ArrayType (moduleDefinition.TypeSystem.Object)));

              var instanceMethod = new GenericInstanceMethod (createReference);
              instanceMethod.GenericArguments.Add (instantiatedType);

              return instanceMethod;
        }
        public TypeDefinition GenerateClass()
        {
            var commandClass = new TypeDefinition(
                GeneratedCommandClassNamespace
                , GeneratedCommandClassName
                , DefaultTypeAttributesForCommand
                , Assets.TypeReferences.Object);

            commandClass.Interfaces.Add(Assets.TypeReferences.ICommand);

            var genericParameter = new GenericParameter("TParameter", commandClass);
            commandClass.GenericParameters.Add(genericParameter);


            AddFields(commandClass);
            AddConstructors(commandClass);
            AddExecuteMethod(commandClass);
            AddCanExecuteMethod(commandClass);
            Assets.AddCanExecuteChangedEvent(commandClass);

            ModuleDefinition.Types.Add(commandClass);
            Assets.DelegateCommandImplementationWasInjected = true;
            return commandClass;
        }
    void Process(GenericParameter parameter)
    {
        var hasDelegateConstraint = false;
        var hasEnumConstraint = false;
        var attributes = parameter.CustomAttributes;
        for (var i = 0; i < attributes.Count; i++)
        {
            var attribute = attributes[i];
            if (IsDelegateConstraintAttribute(attribute))
            {
                hasDelegateConstraint = true;
                parameter.Attributes = GenericParameterAttributes.NonVariant;
                parameter.Constraints.Clear();

                var typeReference = GetDelegateType(attribute, parameter);

                parameter.Constraints.Add(typeReference);
                attributes.RemoveAt(i--);
            }
            else if (IsEnumConstraintAttribute(attribute))
            {
                hasEnumConstraint = true;
                parameter.Attributes = GenericParameterAttributes.NonVariant | GenericParameterAttributes.NotNullableValueTypeConstraint;
                parameter.Constraints.Clear();

                var typeReference = GetEnumType(attribute, parameter);

                parameter.Constraints.Add(typeReference);
                attributes.RemoveAt(i--);
            }
        }
        if (hasDelegateConstraint && hasEnumConstraint)
        {
            throw new WeavingException("Cannot contain both [EnumConstraint] and [DelegateConstraint].");
        }
    }
Example #28
0
        private TypeReference GetFixedReturnType(TypeReference type)
        {
            if (type == null)
            {
                return(null);
            }

            if (type.IsOptionalModifier)
            {
                OptionalModifierType omt          = (OptionalModifierType)type;
                TypeReference        fixedElement = GetFixedReturnType(omt.ElementType);
                return(new OptionalModifierType(omt.ModifierType, fixedElement));
            }

            if (type.IsRequiredModifier)
            {
                RequiredModifierType rmt          = (RequiredModifierType)type;
                TypeReference        fixedElement = GetFixedReturnType(rmt.ElementType);
                return(new RequiredModifierType(rmt.ModifierType, fixedElement));
            }

            if (type.IsGenericParameter)
            {
                return(GetActualType(type));
            }
            if (type.IsArray)
            {
                ArrayType     at               = (ArrayType)type;
                int           rank             = at.Rank;
                TypeReference arrayElementType = at.ElementType;
                arrayElementType = GetFixedReturnType(arrayElementType);
                return(new ArrayType(arrayElementType, rank));
            }

            if (type.IsPointer)
            {
                TypeReference fixedElement = GetFixedReturnType(((PointerType)type).ElementType);
                return(new PointerType(fixedElement));
            }

            if (type.IsByReference)
            {
                TypeReference fixedElement = GetFixedReturnType(((ByReferenceType)type).ElementType);
                return(new ByReferenceType(fixedElement));
            }


            if (type.IsGenericInstance && DeclaringType.IsGenericInstance)
            {
                GenericInstanceType result = type as GenericInstanceType;
                GenericInstanceType declaringTypeGenericInstance = DeclaringType as GenericInstanceType;
                TypeReference       declaringElementType         = DeclaringType.GetElementType();
                for (int i = 0; i < result.GenericArguments.Count; i++)
                {
                    GenericParameter currentParam = result.GenericArguments[i] as GenericParameter;
                    if (currentParam != null && currentParam.Owner == declaringElementType)
                    {
                        if (declaringTypeGenericInstance.PostionToArgument.ContainsKey(currentParam.Position))
                        {
                            result.ReplaceGenericArgumentAt(i, declaringTypeGenericInstance.PostionToArgument[currentParam.position]);
                        }
                    }
                }
                return(result);
            }

            return(type);
        }
 private static TypeReference ResolveIfNeeded(IGenericInstance genericInstanceMethod, IGenericInstance genericInstanceType, GenericParameter genericParameterElement)
 {
     return((genericParameterElement.MetadataType == MetadataType.MVar)
                         ? (genericInstanceMethod != null ? genericInstanceMethod.GenericArguments[genericParameterElement.Position] : genericParameterElement)
                         : genericInstanceType.GenericArguments[genericParameterElement.Position]);
 }
Example #30
0
 public void RemoveGenericConstraintMapping(GenericParameter generic_parameter)
 {
     GenericConstraints.Remove(generic_parameter.token.RID);
 }
Example #31
0
 static bool AreSame(GenericParameter a, GenericParameter b)
 {
     return a.Position == b.Position;
 }
Example #32
0
 protected override TypeReference[] GetInterfaces(GenericParameter[] genericParameters) => new[] { !SourceType.HasGenericParameters ? Context.ModuleDefinition.Import(SourceType) : Context.ModuleDefinition.Import(SourceType).MakeGenericInstanceType(genericParameters) };
Example #33
0
 private AnalysisNet.Types.IGenericParameterReference ExtractType(Cecil.GenericParameter typeref)
 {
     return(genericParameterExtractor.GetGenericParameter(typeref));
 }
Example #34
0
 public RuntimeTypeHandleForGenericParameterValue(GenericParameter genericParameter)
 {
     Kind             = ValueNodeKind.RuntimeTypeHandleForGenericParameter;
     GenericParameter = genericParameter;
 }
 public void Add(GenericParameter value)
 {
     List.Add(value);
 }
 public bool Contains(GenericParameter value)
 {
     return(List.Contains(value));
 }
 public int IndexOf(GenericParameter value)
 {
     return(List.IndexOf(value));
 }
 public void Insert(int index, GenericParameter value)
 {
     List.Insert(index, value);
 }
Example #39
0
        protected virtual void CreateCoroutineType()
        {
            var typeGeneric = new GenericParameter [method.DeclaringType.GenericParameters.Count];
            var methodGeneric = new GenericParameter [method.GenericParameters.Count];

            int i = typeGeneric.Length + methodGeneric.Length;

            var futureName = string.Format ("__c{0}_{1}_{2}_impl", asyncMethodID++, method.Name.Replace ("`", "$"),
                                            string.Join ("_", method.Parameters.Select (p => p.ParameterType.Name.Replace ("`", "$")).ToArray ()));
            if (i > 0)
                futureName += string.Format ("`{0}", i);

            coroutineType = new TypeDefinition (null, futureName, Mono.Cecil.TypeAttributes.NestedPrivate | Mono.Cecil.TypeAttributes.Sealed | Mono.Cecil.TypeAttributes.BeforeFieldInit);

            //if (debug)
            //	coroutineType.CustomAttributes.Add (new CustomAttribute (module.Import (compilerGenerated)));

            // copy all generic parameters from method's containing type and method into new coroutinefuture type
            for (i = 0; i < typeGeneric.Length; i++) {
                typeGeneric [i] = new GenericParameter (method.DeclaringType.GenericParameters [i].Name, coroutineType);
                foreach (var constraint in method.DeclaringType.GenericParameters [i].Constraints)
                    typeGeneric [i].Constraints.Add (constraint);
                foreach (var attr in method.DeclaringType.GenericParameters [i].CustomAttributes)
                    typeGeneric [i].CustomAttributes.Add (attr);
                coroutineType.GenericParameters.Add (typeGeneric [i]);
            }
            for (i = 0; i < methodGeneric.Length; i++) {
                methodGeneric [i] = new GenericParameter (method.GenericParameters [i].Name, coroutineType);
                foreach (var constraint in method.GenericParameters [i].Constraints)
                    methodGeneric [i].Constraints.Add (constraint);
                foreach (var attr in method.GenericParameters [i].CustomAttributes)
                    methodGeneric [i].CustomAttributes.Add (attr);
                coroutineType.GenericParameters.Add (methodGeneric [i]);
            }

            if (typeGeneric.Length != 0 || methodGeneric.Length != 0) {
                genType = new GenericInstanceType (coroutineType);
                foreach (var genParam in coroutineType.GenericParameters)
                    genType.GenericArguments.Add (genParam);
            }

            // add fields for original method's "this" and other arguments..
            i = 0;
            string name;
            FieldDefinition fld;

            if (method.HasThis) {

                var thisType = method.DeclaringType.MakeGeneric (typeGeneric);
                argsFields [0] = fld = new FieldDefinition ("$ths", Mono.Cecil.FieldAttributes.Private | Mono.Cecil.FieldAttributes.InitOnly, thisType);
                coroutineType.Fields.Add (fld);
                if (genType != null)
                    argsFields [0] = new FieldReference (fld.Name, fld.FieldType, genType);
                i = 1;

            }
            foreach (var arg in method.Parameters) {
                var paramType = arg.ParameterType.CopyGeneric (coroutineType, skews);

                name = "$a" + i;
                if (debug)
                    name = arg.Name ?? name;
                argsFields [i] = fld = new FieldDefinition (name, Mono.Cecil.FieldAttributes.Private, paramType);
                coroutineType.Fields.Add (fld);
                if (genType != null)
                    argsFields [i] = new FieldReference (fld.Name, fld.FieldType, genType);
                i++;
            }

            // create a field for each local
            i = 0;
            foreach (var local in method.Body.Variables) {
                name = "$l" + i;
                if (debug)
                    name = local.Name ?? name;
                localsFields [i] = fld = new FieldDefinition (name, Mono.Cecil.FieldAttributes.Private, local.VariableType.CopyGeneric (coroutineType, skews));
                coroutineType.Fields.Add (fld);
                if (genType != null)
                    localsFields [i] = new FieldReference (fld.Name, fld.FieldType, genType);
                i++;
            }
        }
 private string GetGenericParameterName(GenericParameter genericParameter)
 {
     if (genericParameter.Owner is TypeReference)
     {
         return "!" + genericParameter.Position;
     }
     else
     {
         return "!!" + genericParameter.Position;
     }
 }
Example #41
0
 public ConstraintCollection(GenericParameter container)
 {
     m_container = container;
 }
Example #42
0
        private TypeReference ImportTypeSpecification(TypeReference type, ImportGenericContext context)
        {
            switch (type.etype)
            {
            case ElementType.SzArray:
            {
                ArrayType arrayType = (ArrayType)type;
                return(new ArrayType(ImportType(arrayType.ElementType, context)));
            }

            case ElementType.Ptr:
            {
                PointerType pointerType = (PointerType)type;
                return(new PointerType(ImportType(pointerType.ElementType, context)));
            }

            case ElementType.ByRef:
            {
                ByReferenceType byReferenceType = (ByReferenceType)type;
                return(new ByReferenceType(ImportType(byReferenceType.ElementType, context)));
            }

            case ElementType.Pinned:
            {
                PinnedType pinnedType = (PinnedType)type;
                return(new PinnedType(ImportType(pinnedType.ElementType, context)));
            }

            case ElementType.Sentinel:
            {
                SentinelType sentinelType = (SentinelType)type;
                return(new SentinelType(ImportType(sentinelType.ElementType, context)));
            }

            case ElementType.FnPtr:
            {
                FunctionPointerType functionPointerType  = (FunctionPointerType)type;
                FunctionPointerType functionPointerType2 = new FunctionPointerType
                {
                    HasThis           = functionPointerType.HasThis,
                    ExplicitThis      = functionPointerType.ExplicitThis,
                    CallingConvention = functionPointerType.CallingConvention,
                    ReturnType        = ImportType(functionPointerType.ReturnType, context)
                };
                if (!functionPointerType.HasParameters)
                {
                    return(functionPointerType2);
                }
                for (int j = 0; j < functionPointerType.Parameters.Count; j++)
                {
                    functionPointerType2.Parameters.Add(new ParameterDefinition(ImportType(functionPointerType.Parameters[j].ParameterType, context)));
                }
                return(functionPointerType2);
            }

            case ElementType.CModOpt:
            {
                OptionalModifierType optionalModifierType = (OptionalModifierType)type;
                return(new OptionalModifierType(ImportType(optionalModifierType.ModifierType, context), ImportType(optionalModifierType.ElementType, context)));
            }

            case ElementType.CModReqD:
            {
                RequiredModifierType requiredModifierType = (RequiredModifierType)type;
                return(new RequiredModifierType(ImportType(requiredModifierType.ModifierType, context), ImportType(requiredModifierType.ElementType, context)));
            }

            case ElementType.Array:
            {
                ArrayType arrayType2 = (ArrayType)type;
                ArrayType arrayType3 = new ArrayType(ImportType(arrayType2.ElementType, context));
                if (arrayType2.IsVector)
                {
                    return(arrayType3);
                }
                Collection <ArrayDimension> dimensions  = arrayType2.Dimensions;
                Collection <ArrayDimension> dimensions2 = arrayType3.Dimensions;
                dimensions2.Clear();
                for (int k = 0; k < dimensions.Count; k++)
                {
                    ArrayDimension arrayDimension = dimensions[k];
                    dimensions2.Add(new ArrayDimension(arrayDimension.LowerBound, arrayDimension.UpperBound));
                }
                return(arrayType3);
            }

            case ElementType.GenericInst:
            {
                GenericInstanceType        genericInstanceType  = (GenericInstanceType)type;
                GenericInstanceType        genericInstanceType2 = new GenericInstanceType(ImportType(genericInstanceType.ElementType, context));
                Collection <TypeReference> genericArguments     = genericInstanceType.GenericArguments;
                Collection <TypeReference> genericArguments2    = genericInstanceType2.GenericArguments;
                for (int i = 0; i < genericArguments.Count; i++)
                {
                    genericArguments2.Add(ImportType(genericArguments[i], context));
                }
                return(genericInstanceType2);
            }

            case ElementType.Var:
            {
                GenericParameter genericParameter2 = (GenericParameter)type;
                if (genericParameter2.DeclaringType == null)
                {
                    throw new InvalidOperationException();
                }
                return(context.TypeParameter(genericParameter2.DeclaringType.FullName, genericParameter2.Position));
            }

            case ElementType.MVar:
            {
                GenericParameter genericParameter = (GenericParameter)type;
                if (genericParameter.DeclaringMethod == null)
                {
                    throw new InvalidOperationException();
                }
                return(context.MethodParameter(context.NormalizeMethodName(genericParameter.DeclaringMethod), genericParameter.Position));
            }

            default:
                throw new NotSupportedException(type.etype.ToString());
            }
        }
Example #43
0
 public virtual void VisitGenericParameter(GenericParameter genparam)
 {
 }
Example #44
0
 private static bool AreSame(GenericParameter a, GenericParameter b) =>
 (a.Position == b.Position);
        public void OnMethod(MethodDefinition method)
        {
            if (method.DeclaringType.IsInterface)
            {
                return;
            }
            if (!method.HasBody)
            {
                if (Verbosity >= 9)
                {
                    Console.WriteLine("method has no body: " + method.FullName);
                }
                return;
            }

            if (method.GenericParameters.Count > 0)
            {
                if (Verbosity >= Verbosities.SkippingVerbose)
                {
                    Console.WriteLine(" . Skipping generic method: " + method.FullName);
                }
                return;
            }

            var processor = method.Body.GetILProcessor();

            foreach (var i in method.Body.Instructions.ToArray())
            {
                if (i.OpCode != OpCodes.Callvirt &&
                    i.OpCode != OpCodes.Call &&
                    i.OpCode != OpCodes.Calli
                    )
                {
                    continue;
                }

                Mono.Cecil.GenericParameter genPar = null;

                MethodReference mr = i.Operand as MethodReference;
                if (mr == null)
                {
                    throw new Exception("Call method does not have MethodReference as Operand.");
                }
                if (!mr.IsGenericInstance)
                {
                    continue;
                }
                if (!mr.FullName.Contains("<"))
                {
//					if(Verbosity >= 8) - shouldn't be reached
                    Console.WriteLine("Skipping method that contains no <");
                    continue;
                }

                if (mr.FullName.Contains(" System."))
                {
                    if (Verbosity >= Verbosities.Skipping)
                    {
                        Console.WriteLine("Skipping method invocation that contains ' System.': "
                                          + mr.FullName + " in " + method.DeclaringType.FullName + "." + method.Name);
                    }
                    continue;
                }

#if CUSTOM // Custom blacklist
                if (!mr.FullName.Contains(" LionFire.") && !mr.FullName.Contains(" Dycen."))
                {
                    if (Verbosity >= Verbosities.Skipping)
                    {
                        Console.WriteLine("Skipping method that is not LionFire or Dycen:"
                                          + mr.FullName + " in " + method.DeclaringType.FullName + "." + method.Name);
                    }
                    continue;
                }
#endif

                var genPars = mr.Resolve().GenericParameters;
                //					Console.WriteLine("TEMP2 - " + genPars.Count);
                //				var genPars = mr.GetGenericParameters(method.Module);
                //				Console.WriteLine("TEMP " + mr.Name);
                //				Console.WriteLine("TEMP genPars.Count " + genPars.Count);

                if (genPars.Count != 1)
                {
                    if (Verbosity >= Verbosities.Warning)
                    {
                        Console.WriteLine("[NS] Replacing methods with more than 1 generic parameter not supported: " + genPars.Count + ": " + mr.FullName + " in " + method.DeclaringType.FullName + "." + method.Name);
                    }
                    continue;
                }
                else
                {
                    genPar = genPars[0];
//					var resolved = genPar.Resolve();
//					Console.WriteLine("NEW -- <" + (resolved == null ? "null" : resolved.Name) + ">");
                    if (Verbosity >= 10)
                    {
                        Console.WriteLine("NEW |- <" + genPar + ">");
                    }
                }


                #region string genericParameter = ...;
                string         genericParameter;
                Type           genericTypeParameter;
                TypeDefinition genericTypeParameterDefinition = null;
                {
                    string n = mr.FullName.Split(' ')[1];
                    n = n.Split(new string[] { "::" }, StringSplitOptions.RemoveEmptyEntries)[1];
                    int startI = n.IndexOf('<') + 1;
                    int stack  = 0;
                    int endI   = startI + 1;
                    while (stack > 0 || n[endI] != '>')
                    {
                        if (n[endI] == '<')
                        {
                            stack++;
                        }
                        if (n[endI] == '>')
                        {
                            stack--;
                        }
                        endI++;
                    }

                    int length = endI - startI;
                    genericParameter = n.Substring(startI, length);

//					if(genericParameter.StartsWith("!!"))
//					{
//						int genParAliasIndex = Convert.ToInt32(genericParameter.Substring(2));
//
//						var genParAlias = genPars[genParAliasIndex];
//
//
//						genericParameter = genParAlias.FullName;
//						Console.WriteLine("NEW - Generic method alias param: " + genericParameter);
//					}
                    //				if(genericParameter.Contains("<") || genericParameter.Contains(">"))
                    //				{
                    //					Console.WriteLine("Unsupported generic method ("+mr.FullName+") with generic parameter: " + genericParameter);
                    //					skipped++;
                    //					continue;
                    //				}

                    if (Verbosity >= 8)
                    {
                        Console.WriteLine("Generic method param: " + genericParameter);
                    }

                    genericTypeParameter = Type.GetType(genericParameter, false);

                    //if(genericTypeParameter == null)
                    {
                        foreach (ModuleDefinition modDef in ads.SelectMany(assDef => assDef.Modules))
                        {
                            //						foreach(var modType in modDef.Types)
                            //						{
                            //							Console.WriteLine("ccc - " + modType);
                            //						}
                            genericTypeParameterDefinition = modDef.Types.Where(td => td.FullName == genericParameter
                                                                                //							                      && !td.IsGenericInstance
                                                                                ).FirstOrDefault();

                            if (genericTypeParameterDefinition != null)
                            {
                                if (Verbosity >= 9)
                                {
                                    Console.WriteLine("TODO - got genTD: " + genericTypeParameterDefinition);
                                }
                                break;
                            }
                        }
                        if (genericTypeParameterDefinition == null)
                        {
                            if (Verbosity >= 8)
                            {
                                Console.WriteLine(" x Could not get TypeDefinition for " + genericParameter);
                            }
                            // No continue, this is not a problem
                        }

                        if (genericTypeParameter == null && genericTypeParameterDefinition == null)
                        {
                            if (Verbosity >= Verbosities.Error)
                            {
                                Console.WriteLine(" x - Failed to get Type for " + genericParameter + " in invocation: " + mr.FullName + " in method " + method.FullName);
                            }
                            skipped++;
                            continue;
                        }
                    }
                }
                #endregion

#if ONLY_VOID_OR_GENPARM // OLD, now other return types are supported if they are the same as replaced method
                string matchingReturnType = "!!0";
//				genericTypeParameter.FullName;


                if (mr.ReturnType.FullName != "System.Void" &&
                    mr.ReturnType.FullName != matchingReturnType)
//				   && mr.ReturnType.FullName != genericTypeParameter.FullName)
                {
                    if (Verbosity >= 3)
                    {
                        Console.WriteLine("   x generic method doesn't return System.Void or '"
                                          + matchingReturnType +
                                          "': " + mr.FullName + ", but instead: " + mr.ReturnType.FullName);
                    }
                    continue;
                }
#endif

//				if(Verbosity >= 9) Console.WriteLine("mr: " + mr.Name);

                TypeDefinition tr = mr.DeclaringType.Resolve();

                MethodDefinition replacementMethod = null;
//				if(mr.DeclaringType.Name == "MultiType")
//				{
//					foreach(MethodDefinition replacementMethod_ in
//						tr.Methods)
//					{
//						Console.WriteLine("z " + replacementMethod_.Name + "    " + replacementMethod_.FullName);
//					}
//				}

                bool noCast = false;

                foreach (MethodDefinition replacementMethod_ in
                         tr.Methods.Where(mr_ => mr_.Name == mr.Name && !mr_.HasGenericParameters))
                {
                    noCast = false;
                    // TODO: Verify parameters
                    if (!replacementMethod_.HasParameters)
                    {
                        continue;
                    }
                    if (replacementMethod_.Parameters.Count != mr.Parameters.Count + 1)
                    {
                        if (Verbosity >= 8)
                        {
                            Console.WriteLine("   x - (alt) candidate replacement method has wrong parameter count: " + replacementMethod_.FullName);
                        }
                        continue;
                    }
//					Console.WriteLine("Replacement param type: "+ replacementMethod_.Parameters[0].ParameterType.FullName);

                    if (replacementMethod_.Parameters[replacementMethod_.Parameters.Count - 1].ParameterType.FullName != "System.Type")
                    {
                        if (Verbosity >= 8)
                        {
                            Console.WriteLine("   x - (alt) candidate replacement does not have Type parameter at the end of parameters : " + replacementMethod_.FullName);
                        }
                        continue;
                    }


                    if (mr.ReturnType.FullName == replacementMethod_.ReturnType.Resolve().FullName)
                    {
                        noCast = true;
                        if (Verbosity >= 9)
                        {
                            Console.WriteLine("   - (alt) generic method and alt method return same type:: " + mr.ReturnType.FullName);
                        }
                    }
                    else if (mr.ReturnType.FullName != "System.Void")                      // Replacement must return object
                    {
                        if (replacementMethod_.ReturnType.Resolve().FullName != "System.Object")
                        {
                            if (Verbosity >= 3)
                            {
                                Console.WriteLine(" [x?] (alt) generic method returns T but candidate replacement method does not return System.Object: " + replacementMethod_.FullName
                                                  + " [[" + mr.FullName + " in " + method.DeclaringType.FullName + "." + method.Name + "]]");
                            }
                            continue;
                        }
                    }
                    if (Verbosity >= 8)
                    {
                        Console.WriteLine("FOUND ALTERNATE METHOD: " + replacementMethod_);
                    }
                    replacementMethod = replacementMethod_;
                    break;                     // FUTURE: don't break here, keep going to see if there are multiple (ambiguous) matches and throw/output error
                }
                if (replacementMethod == null)
                {
                    if (!(" " + mr.FullName).Contains(" System."))
                    {
                        if (Verbosity >= Verbosities.Warning)
                        {
                            Console.WriteLine("[__] No alternate found for "
                                              + mr.FullName + " in " + method.DeclaringType.FullName + "." + method.Name);
                        }
//						                  + mr.DeclaringType.FullName+"." +mr.Name + "(...)");
                    }
                    skipped++;
                    continue;
                }

//				if(mr.Name != "TestMethod") continue; // TEMP
                if (Verbosity >= Verbosities.Success)
                {
                    Console.WriteLine(" O Replacing " + mr.FullName
                                      + " " + mr.GenericParameters.Count + " generic parameters"
                                      + " " + mr.Parameters.Count + " parameters"
                                      + " | " + mr.GetElementMethod().FullName + ""
                                      + " | " + mr.GetElementMethod().HasGenericParameters + ""
                                      + " | " + mr.GetElementMethod().GenericParameters[0].Name + ""
                                      );
                }

//				if(Verbosity >= 6)
//					Console.WriteLine("Resolved non-specific generic method: " + mr.FullName);

//				if(Verbosity >= 8) Console.WriteLine("RESOLVED TYPE: " + genericTypeParameter);

//				var typeModuleDefinition = ModuleDefinition.ReadModule(type.Module.Assembly.Location);
//				var typeDefinition = typeModuleDefinition.Types.Where(td => td.FullName == genericParameter).FirstOrDefault();
//				if(typeDefinition != null && Verbosity >= 5)
//				{
//					Console.WriteLine("Resolved typeDefinition: " + typeDefinition);
//				}
//				else
//				{
//					Console.WriteLine("Failed to resolve typeDefinition: " + type.FullName);
////					foreach(var td in ModuleDefinition.ReadModule(type.Module.Assembly.Location).Types)
////					{
////						Console.WriteLine(" ... " + td.FullName);
////					}
//					continue;
//				}

//				method.Module.Import(type); // try removing this

//				IMetadataScope scope = method.Module;
//				var typeRef = new TypeReference(type.Namespace, type.Name, typeModuleDefinition, scope, type.IsValueType);
//				Console.WriteLine("TypeRef: "+ typeRef);

//				method.Module.Import(type);
                var replacementMethodImported = method.Module.Import(replacementMethod);

                // IL_0000:  ldtoken Rewriter.TestClass

                if (genericTypeParameter != null)
                {
                    processor.InsertBefore(i, processor.Create(OpCodes.Ldtoken, method.Module.Import(genericTypeParameter)));
                }
                else
                {
                    processor.InsertBefore(i, processor.Create(OpCodes.Ldtoken, method.Module.Import(genericTypeParameterDefinition)));
                }

                // IL_0005:  call class [mscorlib]System.Type class
                //              [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)

                var             gtfh    = typeof(Type).GetMethod("GetTypeFromHandle");
                MethodReference gtfhRef = method.Module.Import(gtfh, mr);

                processor.InsertBefore(i, processor.Create(OpCodes.Call, gtfhRef));

                // IL_000a:  call void class Rewriter.TestClass::TestMethod(class [mscorlib]System.Type)
                var callMethod = processor.Create(i.OpCode, replacementMethodImported);
                processor.InsertAfter(i, callMethod);

                #region Cast the result, if it exists

                if (mr.ReturnType.FullName != "System.Void" && !noCast)
                {
                    string castAssembly;
                    string castType;

                    if (genericTypeParameter != null)
                    {
                        castAssembly = genericTypeParameter.Assembly.GetName(false).Name;
                        castType     = "[" + castAssembly + "]" + genericTypeParameter.FullName;
                    }
                    else if (genericTypeParameterDefinition != null)
                    {
                        castAssembly = "";
                        castType     = genericTypeParameterDefinition.ToString();
//						var resolvedGTPD = genericTypeParameterDefinition.Resolve();
//						resolvedGTPD.FullName
                    }
                    else
                    {
                        castType = "???";
                        Console.WriteLine("INTERNAL ERROR - genericTypeParameter not set for " + mr.FullName + ". genericTypeParameterDefinition:" + genericTypeParameterDefinition.Resolve());
                        continue;
                    }

                    //					castAssembly = castAssembly.Substring(castAssembly.IndexOf(","));
                    if (Verbosity > 8)
                    {
                        Console.WriteLine("CAST to " + castType + " | " + genericTypeParameterDefinition);
                    }
                    var importedGenericType = mr.Module.Import(genericTypeParameterDefinition);
                    processor.InsertAfter(callMethod,
                                          processor.Create(OpCodes.Castclass, importedGenericType));
                }

                #endregion

                processor.Remove(i);
                replaced++;

//				if(Verbosity >= Verbosities.Success)
//					Console.WriteLine(" - " + ((MethodReference)i.Operand).Name + " replaced with " + replacementMethod.FullName);


//				mr.GetGenericParameters(null);
//
//			if(method.GenericParameters.Count == 0) return;
//
//			if(method.GenericParameters.Count > 1)
//			{
//				Console.WriteLine("Warning: cannot handle more than one generic parameter yet: " +
//				                  method.DeclaringType.FullName + "." + method.Name);
//				return;
//			}
//
//			var body = method.Body;
//			body.Instructions
//			if(method.GenericParameters.Count == 1)
//			{
//			}
            }
        }
        protected bool IsParameterCopyNeeded (FunctionAnalysis2ndPass sa, string parameterName, JSExpression expression, out GenericParameter relevantParameter) {
            if (!IsCopyNeeded(expression, out relevantParameter))
                return false;

            if (sa == null)
                return true;

            if (!OptimizeCopies)
                return true;

            bool modified = true, escapes = true, isResult = false;

            if (parameterName != null) {
                modified = sa.ModifiedVariables.Contains(parameterName);
                escapes = sa.EscapingVariables.Contains(parameterName);
                isResult = sa.ResultVariable == parameterName;
            }

            return modified || (escapes && !isResult);
        }
Example #47
0
        internal static GenericParameter Clone(GenericParameter gp, ImportContext context)
        {
            GenericParameter ngp;
            if (gp.Owner is TypeReference)
                ngp = new GenericParameter (gp.m_name, context.GenericContext.Type);
            else if (gp.Owner is MethodReference)
                ngp = new GenericParameter (gp.m_name, context.GenericContext.Method);
            else
                throw new NotSupportedException ();

            ngp.Position = gp.Owner.GenericParameters.IndexOf (gp);
            ngp.Attributes = gp.Attributes;

            foreach (TypeReference constraint in gp.Constraints)
                ngp.Constraints.Add (context.Import (constraint));
            foreach (CustomAttribute ca in gp.CustomAttributes)
                ngp.CustomAttributes.Add (CustomAttribute.Clone (ca, context));

            return ngp;
        }
Example #48
0
        internal static MethodDefinition Clone(MethodDefinition meth, ImportContext context)
        {
            MethodDefinition nm = new MethodDefinition(
                meth.Name,
                RVA.Zero,
                meth.Attributes,
                meth.ImplAttributes,
                meth.HasThis,
                meth.ExplicitThis,
                meth.CallingConvention);

            context.GenericContext.Method = nm;

            foreach (GenericParameter p in meth.GenericParameters)
            {
                nm.GenericParameters.Add(GenericParameter.Clone(p, context));
            }

            nm.ReturnType.ReturnType = context.Import(meth.ReturnType.ReturnType);

            if (meth.ReturnType.HasConstant)
            {
                nm.ReturnType.Constant = meth.ReturnType.Constant;
            }

            if (meth.ReturnType.MarshalSpec != null)
            {
                nm.ReturnType.MarshalSpec = meth.ReturnType.MarshalSpec;
            }

            foreach (CustomAttribute ca in meth.ReturnType.CustomAttributes)
            {
                nm.ReturnType.CustomAttributes.Add(CustomAttribute.Clone(ca, context));
            }

            if (meth.PInvokeInfo != null)
            {
                nm.PInvokeInfo = meth.PInvokeInfo;                 // TODO: import module ?
            }
            foreach (ParameterDefinition param in meth.Parameters)
            {
                nm.Parameters.Add(ParameterDefinition.Clone(param, context));
            }
            foreach (MethodReference ov in meth.Overrides)
            {
                nm.Overrides.Add(context.Import(ov));
            }
            foreach (CustomAttribute ca in meth.CustomAttributes)
            {
                nm.CustomAttributes.Add(CustomAttribute.Clone(ca, context));
            }
            foreach (SecurityDeclaration sec in meth.SecurityDeclarations)
            {
                nm.SecurityDeclarations.Add(SecurityDeclaration.Clone(sec));
            }

            if (meth.Body != null)
            {
                nm.Body = MethodBody.Clone(meth.Body, nm, context);
            }

            return(nm);
        }
        protected bool IsCopyNeeded (JSExpression value, out GenericParameter relevantParameter) {
            relevantParameter = null;

            if ((value == null) || (value.IsNull))
                return false;

            while (value is JSReferenceExpression)
                value = ((JSReferenceExpression)value).Referent;

            var sce = value as JSStructCopyExpression;
            if (sce != null)
                return false;

            var valueType = value.GetActualType(TypeSystem);
            var valueTypeDerefed = TypeUtil.DereferenceType(valueType) ?? valueType;
            var cte = value as JSChangeTypeExpression;
            var cast = value as JSCastExpression;

            TypeReference originalType;
            int temp;

            if (cte != null) {
                originalType = cte.Expression.GetActualType(TypeSystem);
            } else if (cast != null) {
                originalType = cast.Expression.GetActualType(TypeSystem);
            } else {
                originalType = null;
            }

            if (originalType != null) {
                originalType = TypeUtil.FullyDereferenceType(originalType, out temp);

                if (!IsStructOrGenericParameter(valueTypeDerefed) && !IsStructOrGenericParameter(originalType))
                    return false;

                relevantParameter = (originalType as GenericParameter) ?? (valueTypeDerefed as GenericParameter);
            } else {
                if (!IsStructOrGenericParameter(valueTypeDerefed))
                    return false;

                relevantParameter = (valueTypeDerefed as GenericParameter);
            }

            if (IsTypeExcludedFromCopies(valueType)) 
                return false;

            var iae = value as JSInitializerApplicationExpression;

            if (
                (value is JSLiteral) ||
                (value is JSNewExpression) ||
                (value is JSPassByReferenceExpression) ||
                (value is JSNewBoxedVariable) ||
                (value is JSDefaultValueLiteral) ||
                ((iae != null) && ((iae.Target is JSNewExpression) || (iae.Target is JSDefaultValueLiteral)))
            ) {
                return false;
            }

            if (!OptimizeCopies)
                return true;

            if (IsImmutable(value)) {
                return false;
            }

            var valueDot = value as JSDotExpressionBase;

            // The value is being read out of an element proxy, so no copy is necessary - the read unpacks the value
            //  on demand from the packed array.
            if ((valueDot != null) && PackedArrayUtil.IsElementProxy(valueDot.Target))
                return false;

            var valueTypeInfo = TypeInfo.GetExisting(valueType);
            if ((valueTypeInfo != null) && valueTypeInfo.IsImmutable)
                return false;
            
            // If the expression is a parameter that is only used once and isn't aliased,
            //  we don't need to copy it.
            var rightVar = value as JSVariable;
            if (rightVar != null) {
                int referenceCount;
                if (
                    ReferenceCounts.TryGetValue(rightVar.Identifier, out referenceCount) &&
                    (referenceCount == 1) && !rightVar.IsReference && rightVar.IsParameter &&
                    !SecondPass.VariableAliases.ContainsKey(rightVar.Identifier)
                ) {
                    if (Tracing)
                        Debug.WriteLine(String.Format("Returning false from IsCopyNeeded for parameter {0} because reference count is 1 and it has no aliases", value));

                    return false;
                }
            }

            var rightInvocation = value as JSInvocationExpression;
            if (rightInvocation == null)
                return true;

            var invokeMethod = rightInvocation.JSMethod;
            if (invokeMethod == null)
                return true;

            var secondPass = GetSecondPass(invokeMethod);
            if (secondPass == null)
                return true;

            // If this expression is the return value of a function invocation, we can eliminate struct
            //  copies if the return value is a 'new' expression.
            if (secondPass.ResultIsNew)
                return false;

            // We can also eliminate a return value copy if the return value is one of the function's 
            //  arguments, and we are sure that argument does not need a copy either.
            if (secondPass.ResultVariable != null) {
                var parameters = invokeMethod.Method.Parameters;
                int parameterIndex = -1;

                for (var i = 0; i < parameters.Length; i++) {
                    if (parameters[i].Name != secondPass.ResultVariable)
                        continue;

                    parameterIndex = i;
                    break;
                }

                if (parameterIndex < 0)
                    return true;

                return IsCopyNeeded(rightInvocation.Arguments[parameterIndex], out relevantParameter);
            }
 
            return true;
        }
Example #50
0
 public bool TryGetGenericConstraintMapping(GenericParameter generic_parameter, out MetadataToken [] mapping)
 {
     return(GenericConstraints.TryGetValue(generic_parameter.token.RID, out mapping));
 }
 protected JSStructCopyExpression MakeCopyForExpression (JSExpression expression, GenericParameter relevantParameter) {
     if (relevantParameter != null)
         return new JSConditionalStructCopyExpression(relevantParameter, expression);
     else
         return new JSStructCopyExpression(expression);
 }
 public void Remove(GenericParameter value)
 {
     List.Remove(value);
 }
        public override void VisitGenericParameter(GenericParameter genparam)
        {

        }
Example #54
0
 static bool AreSame(GenericParameter a, GenericParameter b)
 {
     return(a.Position == b.Position);
 }
Example #55
0
		void MarkGenericParameter (GenericParameter parameter)
		{
			MarkCustomAttributes (parameter);
			foreach (TypeReference constraint in parameter.Constraints)
				MarkType (constraint);
		}
Example #56
0
        public void WriteTypeSignature(TypeReference type)
        {
            if (type == null)
            {
                throw new ArgumentNullException();
            }
            ElementType etype = type.etype;

            switch (etype)
            {
            case ElementType.Var:
            case ElementType.MVar:
            {
                GenericParameter obj = (GenericParameter)type;
                WriteElementType(etype);
                int position = obj.Position;
                if (position == -1)
                {
                    throw new NotSupportedException();
                }
                base.WriteCompressedUInt32((uint)position);
                break;
            }

            case ElementType.GenericInst:
            {
                GenericInstanceType genericInstanceType = (GenericInstanceType)type;
                WriteElementType(ElementType.GenericInst);
                WriteElementType(genericInstanceType.IsValueType ? ElementType.ValueType : ElementType.Class);
                base.WriteCompressedUInt32(MakeTypeDefOrRefCodedRID(genericInstanceType.ElementType));
                WriteGenericInstanceSignature(genericInstanceType);
                break;
            }

            case ElementType.Ptr:
            case ElementType.ByRef:
            case ElementType.Sentinel:
            case ElementType.Pinned:
            {
                TypeSpecification typeSpecification = (TypeSpecification)type;
                WriteElementType(etype);
                WriteTypeSignature(typeSpecification.ElementType);
                break;
            }

            case ElementType.FnPtr:
            {
                FunctionPointerType method = (FunctionPointerType)type;
                WriteElementType(ElementType.FnPtr);
                WriteMethodSignature(method);
                break;
            }

            case ElementType.CModReqD:
            case ElementType.CModOpt:
            {
                IModifierType type2 = (IModifierType)type;
                WriteModifierSignature(etype, type2);
                break;
            }

            case ElementType.Array:
            {
                ArrayType arrayType = (ArrayType)type;
                if (!arrayType.IsVector)
                {
                    WriteArrayTypeSignature(arrayType);
                }
                else
                {
                    WriteElementType(ElementType.SzArray);
                    WriteTypeSignature(arrayType.ElementType);
                }
                break;
            }

            case ElementType.None:
                WriteElementType(type.IsValueType ? ElementType.ValueType : ElementType.Class);
                base.WriteCompressedUInt32(MakeTypeDefOrRefCodedRID(type));
                break;

            default:
                if (TryWriteElementType(type))
                {
                    break;
                }
                throw new NotSupportedException();
            }
        }