Beispiel #1
0
        private AnalysisNet.Types.PointerType ExtractType(Cecil.ByReferenceType typeref)
        {
            AnalysisNet.Types.IType       target = ExtractType(typeref.ElementType);
            AnalysisNet.Types.PointerType type   = new AnalysisNet.Types.PointerType(target);

            return(type);
        }
 public BlittableByReferenceMarshalInfoWriter(ByReferenceType type, MarshalType marshalType, MarshalInfo marshalInfo) : base(type)
 {
     this._elementType = type.ElementType;
     this._elementTypeMarshalInfoWriter = MarshalDataCollector.MarshalInfoWriterFor(this._elementType, marshalType, marshalInfo, false, true, false, null);
     if (this._elementTypeMarshalInfoWriter.MarshaledTypes.Length > 1)
     {
         throw new InvalidOperationException(string.Format("BlittableByReferenceMarshalInfoWriter cannot marshal {0}&.", type.ElementType.FullName));
     }
     this._marshaledTypes = new MarshaledType[] { new MarshaledType(this._elementTypeMarshalInfoWriter.MarshaledTypes[0].Name + "*", this._elementTypeMarshalInfoWriter.MarshaledTypes[0].DecoratedName + "*") };
 }
Beispiel #3
0
        public void RefTypeEquality () {
            var rt1 = new ByReferenceType(T1);
            var rt1_2 = new ByReferenceType(T1_2);
            var rt2 = new ByReferenceType(T2);
            var rt3 = new ByReferenceType(T3);

            Assert.IsFalse(TypeUtil.TypesAreEqual(rt1, T1));

            Assert.IsTrue(TypeUtil.TypesAreEqual(rt1, rt1));
            Assert.IsTrue(TypeUtil.TypesAreEqual(rt1, rt1_2));
            Assert.IsFalse(TypeUtil.TypesAreEqual(rt1, rt2));
            Assert.IsFalse(TypeUtil.TypesAreEqual(rt1, rt3));
        }
Beispiel #4
0
        private static TypeReference CreateSpecs(TypeReference type, Type type_info)
        {
            type = TryCreateGenericInstanceType(type, type_info);
            int[] specs = type_info.specs;
            if (!specs.IsNullOrEmpty <int>())
            {
                for (int i = 0; i < specs.Length; i++)
                {
                    int num3 = specs[i];
                    switch (num3)
                    {
                    case -3:
                        type = new ArrayType(type);
                        break;

                    case -2:
                        type = new ByReferenceType(type);
                        break;

                    case -1:
                        type = new PointerType(type);
                        break;

                    default:
                    {
                        ArrayType type2 = new ArrayType(type);
                        type2.Dimensions.Clear();
                        int num2 = 0;
                        while (true)
                        {
                            if (num2 >= specs[i])
                            {
                                type = type2;
                                break;
                            }
                            ArrayDimension item = new ArrayDimension();
                            type2.Dimensions.Add(item);
                            num2++;
                        }
                        break;
                    }
                    }
                }
            }
            return(type);
        }
        private static TypeReference CreateSpecs(TypeReference type, TypeParser.Type type_info)
        {
            type = TypeParser.TryCreateGenericInstanceType(type, type_info);
            int[] typeInfo = type_info.specs;
            if (typeInfo.IsNullOrEmpty <int>())
            {
                return(type);
            }
            for (int i = 0; i < (int)typeInfo.Length; i++)
            {
                switch (typeInfo[i])
                {
                case -3:
                {
                    type = new ArrayType(type);
                    break;
                }

                case -2:
                {
                    type = new ByReferenceType(type);
                    break;
                }

                case -1:
                {
                    type = new PointerType(type);
                    break;
                }

                default:
                {
                    ArrayType arrayType = new ArrayType(type);
                    arrayType.Dimensions.Clear();
                    for (int j = 0; j < typeInfo[i]; j++)
                    {
                        arrayType.Dimensions.Add(new ArrayDimension());
                    }
                    type = arrayType;
                    break;
                }
                }
            }
            return(type);
        }
Beispiel #6
0
        static TypeReference CreateSpecs(TypeReference type, Type type_info)
        {
            type = TryCreateGenericInstanceType(type, type_info);

            var specs = type_info.specs;

            if (specs.IsNullOrEmpty())
            {
                return(type);
            }

            for (int i = 0; i < specs.Length; i++)
            {
                switch (specs [i])
                {
                case Type.Ptr:
                    type = new PointerType(type);
                    break;

                case Type.ByRef:
                    type = new ByReferenceType(type);
                    break;

                case Type.SzArray:
                    type = new ArrayType(type);
                    break;

                default:
                    var array = new ArrayType(type);
                    array.Dimensions.Clear();

                    for (int j = 0; j < specs [i]; j++)
                    {
                        array.Dimensions.Add(new ArrayDimension());
                    }

                    type = array;
                    break;
                }
            }

            return(type);
        }
Beispiel #7
0
        private static TypeReference CreateSpecs(TypeReference type, Type type_info)
        {
            type = TryCreateGenericInstanceType(type, type_info);
            int[] specs = type_info.specs;
            if (specs.IsNullOrEmpty())
            {
                return(type);
            }
            for (int i = 0; i < specs.Length; i++)
            {
                switch (specs[i])
                {
                case -1:
                    type = new PointerType(type);
                    break;

                case -2:
                    type = new ByReferenceType(type);
                    break;

                case -3:
                    type = new ArrayType(type);
                    break;

                default:
                {
                    ArrayType arrayType = new ArrayType(type);
                    arrayType.Dimensions.Clear();
                    for (int j = 0; j < specs[i]; j++)
                    {
                        arrayType.Dimensions.Add(default(ArrayDimension));
                    }
                    type = arrayType;
                    break;
                }
                }
            }
            return(type);
        }
 static bool compareByReferenceTypes(ByReferenceType a, ByReferenceType b)
 {
     return compareTypeSpecifications(a, b);
 }
        public void Process(MethodDefinition methodDefinition)
        {
            var parameters = methodDefinition.Parameters.Select(CreateMarshalledParameter).ToArray();

            // If everything ended up being a BlittableMarshaller, that means we don't need to do any Marshalling
            if (parameters.All(x => x.Marshaller is BlittableMarshaller))
                return;

            var pinvokeMethod = new MethodDefinition(methodDefinition.Name, methodDefinition.Attributes, methodDefinition.ReturnType);

            // Move PInvokeInfo to underlying native method
            pinvokeMethod.PInvokeInfo = methodDefinition.PInvokeInfo;
            pinvokeMethod.ImplAttributes = methodDefinition.ImplAttributes;
            methodDefinition.PInvokeInfo = null;
            methodDefinition.IsPInvokeImpl = false;
            methodDefinition.ImplAttributes = MethodImplAttributes.IL;

            var context = new MarshalCodeContext(assemblyDefinition, methodDefinition, true);

            // Build method signature
            foreach (var parameter in parameters)
            {
                // Push context
                context.ManagedEmitters.Push(new ParameterMarshalledObjectEmitter(parameter.Parameter));
                if (parameter.IsByReference)
                    context.ManagedEmitters.Push(new ByReferenceMarshalledObjectEmitter());

                // Compute native type
                var nativeType = parameter.Marshaller.GetNativeType(context);
                if (parameter.IsByReference)
                    nativeType = new ByReferenceType(nativeType);

                // Add native parameter to pinvoke method
                parameter.NativeParameter = new ParameterDefinition(parameter.Parameter.Name, parameter.Parameter.Attributes, context.Assembly.MainModule.Import(nativeType));
                pinvokeMethod.Parameters.Add(parameter.NativeParameter);

                // Pop context
                if (parameter.IsByReference)
                    context.ManagedEmitters.Pop();
                context.ManagedEmitters.Pop();
            }

            // First, process marshallers which expect an empty stack (due to loop) and make sure they are stored in a local variable
            foreach (var parameter in parameters.Where(x => x.Marshaller.ContainsLoops || (!(x.Marshaller is BlittableMarshaller) && x.IsByReference)))
            {
                // Store in a local (if we didn't do that, we could end up having loops with things on the stack)
                var variableType = parameter.NativeParameterType;
                parameter.Variable = new VariableDefinition(variableType);
                methodDefinition.Body.Variables.Add(parameter.Variable);

                // Out-only parameter? Nothing to do...
                if (parameter.Parameter.IsOut && !parameter.Parameter.IsIn)
                    continue;

                // Push context
                context.ManagedEmitters.Push(new ParameterMarshalledObjectEmitter(parameter.Parameter));
                if (parameter.IsByReference)
                    context.ManagedEmitters.Push(new ByReferenceMarshalledObjectEmitter());
                context.NativeEmitters.Push(new VariableMarshalledObjectEmitter(parameter.Variable));

                // Convert parameter
                parameter.Marshaller.EmitStoreManagedToNative(context);

                // Pop context
                context.NativeEmitters.Pop();
                if (parameter.IsByReference)
                    context.ManagedEmitters.Pop();
                context.ManagedEmitters.Pop();
            }

            // Each marshaller is responsible for pushing one parameter to the stack
            foreach (var parameter in parameters)
            {
                if (parameter.Variable != null)
                {
                    // Already processed before and stored in a variable
                    context.ILProcessor.Emit(parameter.IsByReference ? OpCodes.Ldloca : OpCodes.Ldloc, parameter.Variable);
                }
                else
                {
                    // Just process and keep it on the stack
                    context.ManagedEmitters.Push(new ParameterMarshalledObjectEmitter(parameter.Parameter));
                    parameter.Marshaller.EmitStoreManagedToNative(context);
                    context.ManagedEmitters.Pop();
                }
            }

            // Emit call
            context.ILProcessor.Emit(OpCodes.Call, pinvokeMethod);

            VariableDefinition returnValue = null;
            Marshaller returnMarshaller = null;
            if (methodDefinition.ReturnType.MetadataType != MetadataType.Void)
            {
                returnMarshaller = Marshaller.FindMarshallerForType(methodDefinition.ReturnType, null);

                // Find native return type
                context.ManagedEmitters.Push(new FakeMarshalledObjectEmitter(methodDefinition.ReturnType));
                var nativeReturnType = returnMarshaller.GetNativeType(context);
                context.ManagedEmitters.Pop();

                // Change return type to native one
                pinvokeMethod.ReturnType = nativeReturnType;

                // Store return value in local variable
                returnValue = new VariableDefinition("returnValue", nativeReturnType);
                methodDefinition.Body.Variables.Add(returnValue);

                context.ILProcessor.Emit(OpCodes.Stloc, returnValue);
            }

            // Emit setup
            // TODO: Force Out parameter to have local variables? (source)
            foreach (var parameter in parameters)
            {
                if (parameter.Parameter.IsOut && parameter.Variable != null)
                {
                    context.NativeEmitters.Push(new VariableMarshalledObjectEmitter(parameter.Variable));
                    context.ManagedEmitters.Push(new ParameterMarshalledObjectEmitter(parameter.Parameter));
                    parameter.Marshaller.EmitStoreNativeToManaged(context);
                    context.ManagedEmitters.Pop();
                    context.NativeEmitters.Pop();
                }
            }

            // TODO: Cleanup

            // Emit return value
            if (returnValue != null)
            {
                // Convert return value to managed type
                context.NativeEmitters.Push(new VariableMarshalledObjectEmitter(returnValue));
                returnMarshaller.EmitStoreNativeToManaged(context);
                context.NativeEmitters.Pop();
            }
            context.ILProcessor.Emit(OpCodes.Ret);

            // Add method to type
            methodDefinition.DeclaringType.Methods.Add(pinvokeMethod);

            methodDefinition.Body.UpdateInstructionOffsets();
        }
        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());
            }
        }
Beispiel #11
0
 /// <summary>
 /// Check the given type.
 /// </summary>
 private bool Check(ByReferenceType type, string context)
 {
     return Check(type.ElementType, context);
 }
Beispiel #12
0
 static TypeReference ImportType(TypeReference typeRef, ModuleDefinition mod,
     MethodReference context, Dictionary<MetadataToken, IMemberDefinition> mems)
 {
     TypeReference ret = typeRef;
     if (typeRef is TypeSpecification)
     {
         if (typeRef is ArrayType)
         {
             ArrayType _spec = typeRef as ArrayType;
             ret = new ArrayType(ImportType(_spec.ElementType, mod, context, mems));
             (ret as ArrayType).Dimensions.Clear();
             foreach (var i in _spec.Dimensions) (ret as ArrayType).Dimensions.Add(i);
         }
         else if (typeRef is GenericInstanceType)
         {
             GenericInstanceType _spec = typeRef as GenericInstanceType;
             ret = new GenericInstanceType(ImportType(_spec.ElementType, mod, context, mems));
             foreach (var i in _spec.GenericArguments) (ret as GenericInstanceType).GenericArguments.Add(ImportType(i, mod, context, mems));
         }
         else if (typeRef is OptionalModifierType)
         {
             ret = new OptionalModifierType(ImportType((typeRef as OptionalModifierType).ModifierType, mod, context, mems),
               ImportType((typeRef as TypeSpecification).ElementType, mod, context, mems));
         }
         else if (typeRef is RequiredModifierType)
         {
             ret = new RequiredModifierType(ImportType((typeRef as RequiredModifierType).ModifierType, mod, context, mems),
                 ImportType((typeRef as TypeSpecification).ElementType, mod, context, mems));
         }
         else if (typeRef is ByReferenceType)
             ret = new ByReferenceType(ImportType((typeRef as TypeSpecification).ElementType, mod, context, mems));
         else if (typeRef is PointerType)
             ret = new PointerType(ImportType((typeRef as TypeSpecification).ElementType, mod, context, mems));
         else if (typeRef is PinnedType)
             ret = new PinnedType(ImportType((typeRef as TypeSpecification).ElementType, mod, context, mems));
         else if (typeRef is SentinelType)
             ret = new SentinelType(ImportType((typeRef as TypeSpecification).ElementType, mod, context, mems));
         else
             throw new NotSupportedException();
     }
     else if (typeRef is GenericParameter)
     {
         if (context == null || (typeRef as GenericParameter).Owner is TypeReference ||
             (typeRef as GenericParameter).Position >= context.GenericParameters.Count)
             return typeRef;
         return context.GenericParameters[(typeRef as GenericParameter).Position];
     }
     else
     {
         if (mems != null && mems.ContainsKey(typeRef.MetadataToken))
             ret = mems[typeRef.MetadataToken] as TypeReference;
         else if (!(ret is TypeDefinition) && typeRef.Scope.Name != "Confuser.Core.Injections.dll")
             ret = mod.Import(ret);
     }
     return ret;
 }
Beispiel #13
0
        public JSNewExpression NewMemberReference(JSExpression target, JSLiteral member)
        {
            var resultType = new ByReferenceType(member.GetActualType(TypeSystem));

            return new JSNewExpression(
                Dot("MemberReference", resultType),
                null, null, target, member
            );
        }
Beispiel #14
0
 static bool compareByReferenceTypes(Type a, ByReferenceType b)
 {
     if (!a.IsByRef)
         return false;
     return compareTypes(a.GetElementType(), b.ElementType);
 }
 private static ByReferenceType ResolveIfNeeded(IGenericInstance genericInstanceMethod, IGenericInstance genericInstanceType, ByReferenceType byReferenceType)
 {
     return(new ByReferenceType(ResolveIfNeeded(genericInstanceMethod, genericInstanceType, byReferenceType.ElementType)));
 }
Beispiel #16
0
 /// <summary>
 /// Finds a type in the input module based on a type in any other module.
 /// </summary>
 /// <returns>The found type or either null or the imported type.</returns>
 /// <param name="type">Type to find.</param>
 /// <param name="context">Context containing some info.</param>
 /// <param name="fallbackToImport">If set to <c>true</c> this method returns the type to find as imported in the input module.</param>
 public virtual TypeReference FindType(TypeReference type, MemberReference context = null, bool fallbackToImport = true, bool loadedDependency = false)
 {
     if (type == null) {
         Log("ERROR: Can't find null type!");
         Log(Environment.StackTrace);
         return null;
     }
     string typeName = RemovePrefixes(type.FullName, type);
     TypeReference foundType = Module.GetType(typeName);
     if (foundType == null && type.IsByReference) {
         foundType = new ByReferenceType(FindType(((ByReferenceType) type).ElementType, context, fallbackToImport));
     }
     if (foundType == null && type.IsArray) {
         foundType = new ArrayType(FindType(((ArrayType) type).ElementType, context, fallbackToImport), ((ArrayType) type).Dimensions.Count);
     }
     if (foundType == null && context != null && type.IsGenericParameter) {
         foundType = FindTypeGeneric(type, context, fallbackToImport);
     }
     if (foundType == null && context != null && type.IsGenericInstance) {
         foundType = new GenericInstanceType(FindType(((GenericInstanceType) type).ElementType, context, fallbackToImport));
         foreach (TypeReference genericArgument in ((GenericInstanceType) type).GenericArguments) {
             ((GenericInstanceType) foundType).GenericArguments.Add(FindType(genericArgument, context));
         }
     }
     if (foundType == null) {
         foreach (ModuleDefinition dependency in Dependencies) {
             foundType = dependency.GetType(typeName);
             if (foundType != null) {
                 return Module.Import(foundType);
             }
         }
     }
     if (foundType != null && foundType.IsDefinition) {
         IsBlacklisted(foundType.Module.Name, foundType.FullName, HasAttribute(foundType.Resolve(), "MonoModBlacklisted"));
     }
     if (type.IsGenericParameter) {
         return foundType ?? (fallbackToImport ? type : null);
     }
     if (foundType == null && type.IsDefinition && type.Scope.Name.EndsWith(".mm")) {
         foundType = PatchType((TypeDefinition) type);
     }
     if (foundType == null) {
         if (!loadedDependency) {
             LoadDependency(type.Scope.Name);
             return FindType(type, context, fallbackToImport, true);
         } else {
             Log("debug: Type not found: " + type.FullName);
             Log("debug: Type scope    : " + type.Scope.Name);
         }
     }
     return foundType ?? (fallbackToImport ? Module.Import(type) : null);
 }
Beispiel #17
0
        public JSNewArrayElementReference NewElementReference (JSExpression target, JSExpression index) {
            var arrayType = TypeUtil.DereferenceType(target.GetActualType(TypeSystem));
            TypeReference resultType;

            if (PackedArrayUtil.IsPackedArrayType(arrayType)) {
                resultType = new ByReferenceType(
                    PackedArrayUtil.GetElementType(arrayType)
                );
            } else if (TypeUtil.IsArray(arrayType)) {
                resultType = new ByReferenceType(
                    TypeUtil.GetElementType(arrayType, true)
                );
            } else {
                throw new ArgumentException("Cannot create a reference to an element of a value of type '" + arrayType.FullName + "'", target.ToString());
            }

            if (PackedArrayUtil.IsPackedArrayType(target.GetActualType(TypeSystem)))
                return new JSNewPackedArrayElementReference(resultType, target, index);
            else
                return new JSNewArrayElementReference(resultType, target, index);
        }
		private string HandleByReferenceType(ByReferenceType parameterType)
		{
			TypeReference elementType = parameterType.ElementType;
			string typeResult = string.Format("{0}@", GetParameterTypeRepresentation(elementType));
			return typeResult;
		}
Beispiel #19
0
        private TypeReference ImportTypeSpecification(TypeReference type, ImportGenericContext context)
        {
            ElementType elementType = type.etype;

            if (elementType > ElementType.CModOpt)
            {
                if (elementType == ElementType.Sentinel)
                {
                    SentinelType sentinelType = (SentinelType)type;
                    return(new SentinelType(this.ImportType(sentinelType.ElementType, context)));
                }
                if (elementType == ElementType.Pinned)
                {
                    PinnedType pinnedType = (PinnedType)type;
                    return(new PinnedType(this.ImportType(pinnedType.ElementType, context)));
                }
            }
            else
            {
                switch (elementType)
                {
                case ElementType.Ptr:
                {
                    PointerType pointerType = (PointerType)type;
                    return(new PointerType(this.ImportType(pointerType.ElementType, context)));
                }

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

                case ElementType.ValueType:
                case ElementType.Class:
                {
                    break;
                }

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

                case ElementType.Array:
                {
                    ArrayType arrayType  = (ArrayType)type;
                    ArrayType arrayType1 = new ArrayType(this.ImportType(arrayType.ElementType, context));
                    if (arrayType.IsVector)
                    {
                        return(arrayType1);
                    }
                    Collection <ArrayDimension> dimensions      = arrayType.Dimensions;
                    Collection <ArrayDimension> arrayDimensions = arrayType1.Dimensions;
                    arrayDimensions.Clear();
                    for (int i = 0; i < dimensions.Count; i++)
                    {
                        ArrayDimension item = dimensions[i];
                        arrayDimensions.Add(new ArrayDimension(item.LowerBound, item.UpperBound));
                    }
                    return(arrayType1);
                }

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

                default:
                {
                    switch (elementType)
                    {
                    case ElementType.SzArray:
                    {
                        ArrayType arrayType2 = (ArrayType)type;
                        return(new ArrayType(this.ImportType(arrayType2.ElementType, context)));
                    }

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

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

                    case ElementType.CModOpt:
                    {
                        OptionalModifierType optionalModifierType = (OptionalModifierType)type;
                        return(new OptionalModifierType(this.ImportType(optionalModifierType.ModifierType, context), this.ImportType(optionalModifierType.ElementType, context)));
                    }
                    }
                    break;
                }
                }
            }
            throw new NotSupportedException(type.etype.ToString());
        }
 public ByReferenceMarshalInfoWriter(ByReferenceType type, MarshalType marshalType, MarshalInfo marshalInfo) : base(type)
 {
     this._elementType = type.ElementType;
     this._elementTypeMarshalInfoWriter = MarshalDataCollector.MarshalInfoWriterFor(type.ElementType, marshalType, marshalInfo, false, true, false, null);
     if (<>f__am$cache0 == null)
     {
Beispiel #21
0
 void doByReferenceType(ByReferenceType byReferenceType)
 {
     if (byReferenceTypes.ContainsKey(byReferenceType))
         return;
     byReferenceTypes[byReferenceType] = true;
     addByReferenceType(byReferenceType);
 }
Beispiel #22
0
        private TypeReference ImportTypeSpecification(TypeReference type, ImportGenericContext context)
        {
            ElementType etype = type.etype;

            if (etype > ElementType.CModOpt)
            {
                if (etype == ElementType.Sentinel)
                {
                    SentinelType type6 = (SentinelType)type;
                    return(new SentinelType(this.ImportType(type6.ElementType, context)));
                }
                if (etype == ElementType.Pinned)
                {
                    PinnedType type5 = (PinnedType)type;
                    return(new PinnedType(this.ImportType(type5.ElementType, context)));
                }
            }
            else
            {
                switch (etype)
                {
                case ElementType.Ptr:
                {
                    PointerType type3 = (PointerType)type;
                    return(new PointerType(this.ImportType(type3.ElementType, context)));
                }

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

                case ElementType.ValueType:
                case ElementType.Class:
                    break;

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

                case ElementType.Array:
                {
                    ArrayType type9  = (ArrayType)type;
                    ArrayType type10 = new ArrayType(this.ImportType(type9.ElementType, context));
                    if (!type9.IsVector)
                    {
                        Collection <ArrayDimension> dimensions  = type9.Dimensions;
                        Collection <ArrayDimension> collection2 = type10.Dimensions;
                        collection2.Clear();
                        for (int i = 0; i < dimensions.Count; i++)
                        {
                            ArrayDimension dimension = dimensions[i];
                            collection2.Add(new ArrayDimension(dimension.LowerBound, dimension.UpperBound));
                        }
                    }
                    return(type10);
                }

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

                default:
                    switch (etype)
                    {
                    case ElementType.SzArray:
                    {
                        ArrayType type2 = (ArrayType)type;
                        return(new ArrayType(this.ImportType(type2.ElementType, context)));
                    }

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

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

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

                    default:
                        break;
                    }
                    break;
                }
            }
            throw new NotSupportedException(type.etype.ToString());
        }
Beispiel #23
0
 static void AppendTypeName(StringBuilder b, TypeReference type)
 {
     if (type == null)
     {
         // could happen when a TypeSpecification has no ElementType; e.g. function pointers in C++/CLI assemblies
         return;
     }
     if (type is GenericInstanceType)
     {
         GenericInstanceType giType = (GenericInstanceType)type;
         AppendTypeNameWithArguments(b, giType.ElementType, giType.GenericArguments);
     }
     else if (type is TypeSpecification)
     {
         AppendTypeName(b, ((TypeSpecification)type).ElementType);
         ArrayType arrayType = type as ArrayType;
         if (arrayType != null)
         {
             b.Append('[');
             for (int i = 0; i < arrayType.Dimensions.Count; i++)
             {
                 if (i > 0)
                 {
                     b.Append(',');
                 }
                 ArrayDimension ad = arrayType.Dimensions[i];
                 if (ad.IsSized)
                 {
                     b.Append(ad.LowerBound);
                     b.Append(':');
                     b.Append(ad.UpperBound);
                 }
             }
             b.Append(']');
         }
         ByReferenceType refType = type as ByReferenceType;
         if (refType != null)
         {
             b.Append('@');
         }
         PointerType ptrType = type as PointerType;
         if (ptrType != null)
         {
             b.Append('*');
         }
     }
     else
     {
         GenericParameter gp = type as GenericParameter;
         if (gp != null)
         {
             b.Append('`');
             if (gp.Owner.GenericParameterType == GenericParameterType.Method)
             {
                 b.Append('`');
             }
             b.Append(gp.Position);
         }
         else if (type.DeclaringType != null)
         {
             AppendTypeName(b, type.DeclaringType);
             b.Append('.');
             b.Append(type.Name);
         }
         else
         {
             b.Append(type.FullName);
         }
     }
 }
Beispiel #24
0
        public JSNewExpression NewElementReference(JSExpression target, JSExpression index)
        {
            var resultType = new ByReferenceType(
                target.GetActualType(TypeSystem).GetElementType()
            );

            return new JSNewExpression(
                Dot("MemberReference", resultType),
                null, null, target, index
            );
        }
        private TypeReference ParseTypeReference()
        {
            TypeReference tr = ClassEditHelper.ParseTypeReference(cboType.SelectedItem, _method.Module);
            if (tr == null)
                tr = ClassEditHelper.ParseTypeReference(cboType.Text.Trim(), _method.Module);
            if (tr != null)
            {
                switch (cboSpecification.SelectedItem as string)
                {
                    case "Array":
                        tr = new ArrayType(tr);
                        break;
                    case "Reference":
                        tr = new ByReferenceType(tr);
                        break;
                    case "Pointer":
                        tr = new PointerType(tr);
                        break;
                    default:
                        break;
                }
            }

            return tr;
        }
Beispiel #26
0
        public JSNewExpression NewReference(JSExpression initialValue)
        {
            var resultType = new ByReferenceType(initialValue.GetActualType(TypeSystem));

            return new JSNewExpression(
                Dot("Variable", resultType),
                null, null, initialValue
            );
        }
        private TypeReference ResolveGenericType(TypeReference originalType, IList<TypeReference> instanceArgs, IList<TypeReference> methodArgs)
        {
            TypeReference resolvedType = originalType;

            // if generic instance, copy generic arguments by recursing into them and building a 'resolved' argument list
            if (originalType is GenericInstanceType)
            {
                var originalGeneric = originalType as GenericInstanceType;

                var resolvedGeneric = new GenericInstanceType(originalGeneric.ElementType);
                resolvedType = resolvedGeneric;

                foreach (var originalArg in originalGeneric.GenericArguments)
                    resolvedGeneric.GenericArguments.Add(
                        ResolveGenericType(originalArg, instanceArgs, methodArgs));
            }

            // if parameter, resolve it using the instance/method generice mapping lists
            else if (originalType is GenericParameter)
            {
                var originalParam = originalType as GenericParameter;

                if (originalParam.Type == GenericParameterType.Type)
                    resolvedType = instanceArgs[originalParam.Position];

                else if (originalParam.Type == GenericParameterType.Method)
                    resolvedType = methodArgs[originalParam.Position];
            }

            else if (originalType is ArrayType)
            {
                var originalArray = originalType as ArrayType;

                resolvedType = new ArrayType(ResolveGenericType(originalArray.ElementType, instanceArgs, methodArgs));
            }

            else if (originalType is ByReferenceType)
            {
                var originalByRef = originalType as ByReferenceType;

                resolvedType = new ByReferenceType(ResolveGenericType(originalByRef.ElementType, instanceArgs, methodArgs));
            }

            return resolvedType;
        }
        private TypeReference ProcessTypeReference(TypeReference type, IGenericParameterProvider owner)
        {
            if (type == null)
                return null;

            // ref types
            if (type is ByReferenceType)
            {
                var elementType = ProcessTypeReference(type.GetElementType(), owner);
                if (elementType != type.GetElementType())
                    type = new ByReferenceType(elementType);
                return type;
            }

            // Generic MVar/Var
            if (type is GenericParameter)
            {
                var genericParameter = (GenericParameter)type;
                if ((genericParameter.MetadataType == MetadataType.MVar
                    || genericParameter.MetadataType == MetadataType.Var) && genericParameter.Owner is MethodReference)
                {
                    if (genericParameter.Owner != null && owner != null)
                    {
                        return owner.GenericParameters.Concat(genericParameter.Owner.GenericParameters).First(x => x.Name == type.Name);
                    }
                }
                return type;
            }

            // Is it an async-related type?
            var asyncBridgeType = asyncBridgeAssembly.MainModule.GetTypeResolved(type.Namespace, type.Name);
            if (asyncBridgeType == null)
                return type;

            // First work on inner TypeReference if there is a GenericInstanceType around it.
            var genericInstanceType = type as GenericInstanceType;
            if (genericInstanceType != null)
            {
                type = genericInstanceType.ElementType;
            }

            var newType = assembly.MainModule.Import(new TypeReference(type.Namespace, type.Name, asyncBridgeAssembly.MainModule, asyncBridgeAssembly.Name, type.IsValueType));

            for (int i = 0; i < type.GenericParameters.Count; ++i)
            {
                newType.GenericParameters.Add(new GenericParameter(type.GenericParameters[i].Name, newType));
                foreach (var constraint in type.GenericParameters[i].Constraints)
                    newType.GenericParameters[i].Constraints.Add(ProcessTypeReference(constraint, newType));
            }

            if (genericInstanceType != null)
            {
                var newGenericType = new GenericInstanceType(newType);
                foreach (var genericArgument in genericInstanceType.GenericArguments)
                {
                    newGenericType.GenericArguments.Add(ProcessTypeReference(genericArgument, newGenericType));
                }
                newType = newGenericType;
            }

            return newType;
        }
Beispiel #29
0
 void addByReferenceType(ByReferenceType brt)
 {
     if (brt == null)
         return;
     addTypeSpecification(brt);
 }
Beispiel #30
0
		TypeReference DoInferTypeForExpression(ILExpression expr, TypeReference expectedType, bool forceInferChildren = false)
		{
			switch (expr.Code) {
					#region Logical operators
				case ILCode.LogicNot:
					if (forceInferChildren) {
						InferTypeForExpression(expr.Arguments.Single(), typeSystem.Boolean);
					}
					return typeSystem.Boolean;
				case ILCode.LogicAnd:
				case ILCode.LogicOr:
					if (forceInferChildren) {
						InferTypeForExpression(expr.Arguments[0], typeSystem.Boolean);
						InferTypeForExpression(expr.Arguments[1], typeSystem.Boolean);
					}
					return typeSystem.Boolean;
				case ILCode.TernaryOp:
					if (forceInferChildren) {
						InferTypeForExpression(expr.Arguments[0], typeSystem.Boolean);
					}
					return TypeWithMoreInformation(
						InferTypeForExpression(expr.Arguments[1], expectedType, forceInferChildren),
						InferTypeForExpression(expr.Arguments[2], expectedType, forceInferChildren)
					);
				case ILCode.NullCoalescing:
					return TypeWithMoreInformation(
						InferTypeForExpression(expr.Arguments[0], expectedType, forceInferChildren),
						InferTypeForExpression(expr.Arguments[1], expectedType, forceInferChildren)
					);
					#endregion
					#region Variable load/store
				case ILCode.Stloc:
					{
						ILVariable v = (ILVariable)expr.Operand;
						if (forceInferChildren) {
							// do not use 'expectedType' in here!
							InferTypeForExpression(expr.Arguments.Single(), v.Type);
						}
						return v.Type;
					}
				case ILCode.Ldloc:
					{
						ILVariable v = (ILVariable)expr.Operand;
						if (v.Type == null && singleLoadVariables.Contains(v)) {
							v.Type = expectedType;
						}
						return v.Type;
					}
				case ILCode.Ldloca:
					return new ByReferenceType(((ILVariable)expr.Operand).Type);
					#endregion
					#region Call / NewObj
				case ILCode.Call:
				case ILCode.Callvirt:
				case ILCode.CallGetter:
				case ILCode.CallvirtGetter:
				case ILCode.CallSetter:
				case ILCode.CallvirtSetter:
					{
						MethodReference method = (MethodReference)expr.Operand;
						if (forceInferChildren) {
							for (int i = 0; i < expr.Arguments.Count; i++) {
								if (i == 0 && method.HasThis) {
									ILExpressionPrefix constraint = expr.GetPrefix(ILCode.Constrained);
									if (constraint != null)
										InferTypeForExpression(expr.Arguments[i], new ByReferenceType((TypeReference)constraint.Operand));
									else if (method.DeclaringType.IsValueType)
										InferTypeForExpression(expr.Arguments[i], new ByReferenceType(method.DeclaringType));
									else
										InferTypeForExpression(expr.Arguments[i], method.DeclaringType);
								} else {
									InferTypeForExpression(expr.Arguments[i], SubstituteTypeArgs(method.Parameters[method.HasThis ? i - 1 : i].ParameterType, method));
								}
							}
						}
						if (expr.Code == ILCode.CallSetter || expr.Code == ILCode.CallvirtSetter) {
							return SubstituteTypeArgs(method.Parameters.Last().ParameterType, method);
						} else {
							TypeReference type = SubstituteTypeArgs(method.ReturnType, method);
							if (expr.GetPrefix(ILCode.PropertyAddress) != null && !(type is ByReferenceType))
								type = new ByReferenceType(type);
							return type;
						}
					}
				case ILCode.Newobj:
					{
						MethodReference ctor = (MethodReference)expr.Operand;
						if (forceInferChildren) {
							for (int i = 0; i < ctor.Parameters.Count; i++) {
								InferTypeForExpression(expr.Arguments[i], SubstituteTypeArgs(ctor.Parameters[i].ParameterType, ctor));
							}
						}
						return ctor.DeclaringType;
					}
				case ILCode.InitCollection:
					return InferTypeForExpression(expr.Arguments[0], expectedType);
				case ILCode.InitCollectionAddMethod:
					{
						MethodReference addMethod = (MethodReference)expr.Operand;
						if (forceInferChildren) {
							for (int i = 1; i < addMethod.Parameters.Count; i++) {
								InferTypeForExpression(expr.Arguments[i-1], SubstituteTypeArgs(addMethod.Parameters[i].ParameterType, addMethod));
							}
						}
						return addMethod.DeclaringType;
					}
					#endregion
					#region Load/Store Fields
				case ILCode.Ldfld:
					if (forceInferChildren)
						InferTypeForExpression(expr.Arguments[0], ((FieldReference)expr.Operand).DeclaringType);
					return GetFieldType((FieldReference)expr.Operand);
				case ILCode.Ldsfld:
					return GetFieldType((FieldReference)expr.Operand);
				case ILCode.Ldflda:
				case ILCode.Ldsflda:
					return new ByReferenceType(GetFieldType((FieldReference)expr.Operand));
				case ILCode.Stfld:
					if (forceInferChildren) {
						InferTypeForExpression(expr.Arguments[0], ((FieldReference)expr.Operand).DeclaringType);
						InferTypeForExpression(expr.Arguments[1], GetFieldType((FieldReference)expr.Operand));
					}
					return GetFieldType((FieldReference)expr.Operand);
				case ILCode.Stsfld:
					if (forceInferChildren)
						InferTypeForExpression(expr.Arguments[0], GetFieldType((FieldReference)expr.Operand));
					return GetFieldType((FieldReference)expr.Operand);
					#endregion
					#region Reference/Pointer instructions
				case ILCode.Ldind_Ref:
					return UnpackPointer(InferTypeForExpression(expr.Arguments[0], null));
				case ILCode.Stind_Ref:
					if (forceInferChildren) {
						TypeReference elementType = UnpackPointer(InferTypeForExpression(expr.Arguments[0], null));
						InferTypeForExpression(expr.Arguments[1], elementType);
					}
					return null;
				case ILCode.Ldobj:
					{
						TypeReference type = (TypeReference)expr.Operand;
						if (expectedType != null) {
							int infoAmount = GetInformationAmount(expectedType);
							if (infoAmount == 1 && GetInformationAmount(type) == 8) {
								// A bool can be loaded from both bytes and sbytes.
								type = expectedType;
							}
							if (infoAmount >= 8 && infoAmount <= 64 && infoAmount == GetInformationAmount(type)) {
								// An integer can be loaded as another integer of the same size.
								// For integers smaller than 32 bit, the signs must match (as loading performs sign extension)
								if (infoAmount >= 32 || IsSigned(expectedType) == IsSigned(type))
									type = expectedType;
							}
						}
						if (forceInferChildren) {
							if (InferTypeForExpression(expr.Arguments[0], new ByReferenceType(type)) is PointerType)
								InferTypeForExpression(expr.Arguments[0], new PointerType(type));
						}
						return type;
					}
				case ILCode.Stobj:
					{
						TypeReference operandType = (TypeReference)expr.Operand;
						TypeReference pointerType = InferTypeForExpression(expr.Arguments[0], new ByReferenceType(operandType));
						TypeReference elementType;
						if (pointerType is PointerType)
							elementType = ((PointerType)pointerType).ElementType;
						else if (pointerType is ByReferenceType)
							elementType = ((ByReferenceType)pointerType).ElementType;
						else
							elementType = null;
						if (elementType != null) {
							// An integer can be stored in any other integer of the same size.
							int infoAmount = GetInformationAmount(elementType);
							if (infoAmount == 1 && GetInformationAmount(operandType) == 8)
								operandType = elementType;
							else if (infoAmount == GetInformationAmount(operandType) && IsSigned(elementType) != null && IsSigned(operandType) != null)
								operandType = elementType;
						}
						if (forceInferChildren) {
							if (pointerType is PointerType)
								InferTypeForExpression(expr.Arguments[0], new PointerType(operandType));
							else if (!IsSameType(operandType, expr.Operand as TypeReference))
								InferTypeForExpression(expr.Arguments[0], new ByReferenceType(operandType));
							InferTypeForExpression(expr.Arguments[1], operandType);
						}
						return operandType;
					}
				case ILCode.Initobj:
					return null;
				case ILCode.DefaultValue:
					return (TypeReference)expr.Operand;
				case ILCode.Localloc:
					if (forceInferChildren) {
						InferTypeForExpression(expr.Arguments[0], typeSystem.Int32);
					}
					if (expectedType is PointerType)
						return expectedType;
					else
						return typeSystem.IntPtr;
				case ILCode.Sizeof:
					return typeSystem.Int32;
				case ILCode.PostIncrement:
				case ILCode.PostIncrement_Ovf:
				case ILCode.PostIncrement_Ovf_Un:
					{
						TypeReference elementType = UnpackPointer(InferTypeForExpression(expr.Arguments[0], null));
						if (forceInferChildren && elementType != null) {
							// Assign expected type to the child expression
							InferTypeForExpression(expr.Arguments[0], new ByReferenceType(elementType));
						}
						return elementType;
					}
					#endregion
					#region Arithmetic instructions
				case ILCode.Not: // bitwise complement
				case ILCode.Neg:
					return InferTypeForExpression(expr.Arguments.Single(), expectedType);
				case ILCode.Add:
					return InferArgumentsInAddition(expr, null, expectedType);
				case ILCode.Sub:
					return InferArgumentsInSubtraction(expr, null, expectedType);
				case ILCode.Mul:
				case ILCode.Or:
				case ILCode.And:
				case ILCode.Xor:
					return InferArgumentsInBinaryOperator(expr, null, expectedType);
				case ILCode.Add_Ovf:
					return InferArgumentsInAddition(expr, true, expectedType);
				case ILCode.Sub_Ovf:
					return InferArgumentsInSubtraction(expr, true, expectedType);
				case ILCode.Mul_Ovf:
				case ILCode.Div:
				case ILCode.Rem:
					return InferArgumentsInBinaryOperator(expr, true, expectedType);
				case ILCode.Add_Ovf_Un:
					return InferArgumentsInAddition(expr, false, expectedType);
				case ILCode.Sub_Ovf_Un:
					return InferArgumentsInSubtraction(expr, false, expectedType);
				case ILCode.Mul_Ovf_Un:
				case ILCode.Div_Un:
				case ILCode.Rem_Un:
					return InferArgumentsInBinaryOperator(expr, false, expectedType);
				case ILCode.Shl:
				case ILCode.Shr:
					if (forceInferChildren)
						InferTypeForExpression(expr.Arguments[1], typeSystem.Int32);
					return InferTypeForExpression(expr.Arguments[0], typeSystem.Int32);
				case ILCode.Shr_Un:
					if (forceInferChildren)
						InferTypeForExpression(expr.Arguments[1], typeSystem.Int32);
					return InferTypeForExpression(expr.Arguments[0], typeSystem.UInt32);
				case ILCode.CompoundAssignment:
					{
						TypeReference varType = InferTypeForExpression(expr.Arguments[0].Arguments[0], null);
						if (forceInferChildren) {
							InferTypeForExpression(expr.Arguments[0], varType);
						}
						return varType;
					}
					#endregion
					#region Constant loading instructions
				case ILCode.Ldnull:
					return typeSystem.Object;
				case ILCode.Ldstr:
					return typeSystem.String;
				case ILCode.Ldftn:
				case ILCode.Ldvirtftn:
					return typeSystem.IntPtr;
				case ILCode.Ldc_I4:
					if (IsBoolean(expectedType) && ((int)expr.Operand == 0 || (int)expr.Operand == 1))
						return typeSystem.Boolean;
					return (IsIntegerOrEnum(expectedType) || expectedType is PointerType) ? expectedType : typeSystem.Int32;
				case ILCode.Ldc_I8:
					return (IsIntegerOrEnum(expectedType) || expectedType is PointerType) ? expectedType : typeSystem.Int64;
				case ILCode.Ldc_R4:
					return typeSystem.Single;
				case ILCode.Ldc_R8:
					return typeSystem.Double;
				case ILCode.Ldc_Decimal:
					return new TypeReference("System", "Decimal", module, module, true);
				case ILCode.Ldtoken:
					if (expr.Operand is TypeReference)
						return new TypeReference("System", "RuntimeTypeHandle", module, module, true);
					else if (expr.Operand is FieldReference)
						return new TypeReference("System", "RuntimeFieldHandle", module, module, true);
					else
						return new TypeReference("System", "RuntimeMethodHandle", module, module, true);
				case ILCode.Arglist:
					return new TypeReference("System", "RuntimeArgumentHandle", module, module, true);
					#endregion
					#region Array instructions
				case ILCode.Newarr:
					if (forceInferChildren)
						InferTypeForExpression(expr.Arguments.Single(), typeSystem.Int32);
					return new ArrayType((TypeReference)expr.Operand);
				case ILCode.InitArray:
					if (forceInferChildren) {
						foreach (ILExpression arg in expr.Arguments)
							InferTypeForExpression(arg, (TypeReference)expr.Operand);
					}
					return new ArrayType((TypeReference)expr.Operand);
				case ILCode.Ldlen:
					return typeSystem.Int32;
				case ILCode.Ldelem_U1:
				case ILCode.Ldelem_U2:
				case ILCode.Ldelem_U4:
				case ILCode.Ldelem_I1:
				case ILCode.Ldelem_I2:
				case ILCode.Ldelem_I4:
				case ILCode.Ldelem_I8:
				case ILCode.Ldelem_R4:
				case ILCode.Ldelem_R8:
				case ILCode.Ldelem_I:
				case ILCode.Ldelem_Ref:
					{
						ArrayType arrayType = InferTypeForExpression(expr.Arguments[0], null) as ArrayType;
						if (forceInferChildren) {
							InferTypeForExpression(expr.Arguments[1], typeSystem.Int32);
						}
						return arrayType != null ? arrayType.ElementType : null;
					}
				case ILCode.Ldelem_Any:
					if (forceInferChildren) {
						InferTypeForExpression(expr.Arguments[1], typeSystem.Int32);
					}
					return (TypeReference)expr.Operand;
				case ILCode.Ldelema:
					{
						ArrayType arrayType = InferTypeForExpression(expr.Arguments[0], null) as ArrayType;
						if (forceInferChildren)
							InferTypeForExpression(expr.Arguments[1], typeSystem.Int32);
						return arrayType != null ? new ByReferenceType(arrayType.ElementType) : null;
					}
				case ILCode.Stelem_I:
				case ILCode.Stelem_I1:
				case ILCode.Stelem_I2:
				case ILCode.Stelem_I4:
				case ILCode.Stelem_I8:
				case ILCode.Stelem_R4:
				case ILCode.Stelem_R8:
				case ILCode.Stelem_Ref:
				case ILCode.Stelem_Any:
					{
						ArrayType arrayType = InferTypeForExpression(expr.Arguments[0], null) as ArrayType;
						if (forceInferChildren) {
							InferTypeForExpression(expr.Arguments[1], typeSystem.Int32);
							if (arrayType != null) {
								InferTypeForExpression(expr.Arguments[2], arrayType.ElementType);
							}
						}
						return arrayType != null ? arrayType.ElementType : null;
					}
					#endregion
					#region Conversion instructions
				case ILCode.Conv_I1:
				case ILCode.Conv_Ovf_I1:
				case ILCode.Conv_Ovf_I1_Un:
					return HandleConversion(8, true, expr.Arguments[0], expectedType, typeSystem.SByte);
				case ILCode.Conv_I2:
				case ILCode.Conv_Ovf_I2:
				case ILCode.Conv_Ovf_I2_Un:
					return HandleConversion(16, true, expr.Arguments[0], expectedType, typeSystem.Int16);
				case ILCode.Conv_I4:
				case ILCode.Conv_Ovf_I4:
				case ILCode.Conv_Ovf_I4_Un:
					return HandleConversion(32, true, expr.Arguments[0], expectedType, typeSystem.Int32);
				case ILCode.Conv_I8:
				case ILCode.Conv_Ovf_I8:
				case ILCode.Conv_Ovf_I8_Un:
					return HandleConversion(64, true, expr.Arguments[0], expectedType, typeSystem.Int64);
				case ILCode.Conv_U1:
				case ILCode.Conv_Ovf_U1:
				case ILCode.Conv_Ovf_U1_Un:
					return HandleConversion(8, false, expr.Arguments[0], expectedType, typeSystem.Byte);
				case ILCode.Conv_U2:
				case ILCode.Conv_Ovf_U2:
				case ILCode.Conv_Ovf_U2_Un:
					return HandleConversion(16, false, expr.Arguments[0], expectedType, typeSystem.UInt16);
				case ILCode.Conv_U4:
				case ILCode.Conv_Ovf_U4:
				case ILCode.Conv_Ovf_U4_Un:
					return HandleConversion(32, false, expr.Arguments[0], expectedType, typeSystem.UInt32);
				case ILCode.Conv_U8:
				case ILCode.Conv_Ovf_U8:
				case ILCode.Conv_Ovf_U8_Un:
					return HandleConversion(64, false, expr.Arguments[0], expectedType, typeSystem.UInt64);
				case ILCode.Conv_I:
				case ILCode.Conv_Ovf_I:
				case ILCode.Conv_Ovf_I_Un:
					return HandleConversion(NativeInt, true, expr.Arguments[0], expectedType, typeSystem.IntPtr);
				case ILCode.Conv_U:
				case ILCode.Conv_Ovf_U:
				case ILCode.Conv_Ovf_U_Un:
					return HandleConversion(NativeInt, false, expr.Arguments[0], expectedType, typeSystem.UIntPtr);
				case ILCode.Conv_R4:
					if (forceInferChildren) {
						InferTypeForExpression(expr.Arguments[0], typeSystem.Single);
					}
					return typeSystem.Single;
				case ILCode.Conv_R8:
					if (forceInferChildren) {
						InferTypeForExpression(expr.Arguments[0], typeSystem.Double);
					}
					return typeSystem.Double;
				case ILCode.Conv_R_Un:
					return (expectedType != null  && expectedType.MetadataType == MetadataType.Single) ? typeSystem.Single : typeSystem.Double;
				case ILCode.Castclass:
				case ILCode.Isinst:
				case ILCode.Unbox_Any:
					return (TypeReference)expr.Operand;
				case ILCode.Box:
					if (forceInferChildren)
						InferTypeForExpression(expr.Arguments.Single(), (TypeReference)expr.Operand);
					return (TypeReference)expr.Operand;
					#endregion
					#region Comparison instructions
				case ILCode.Ceq:
					if (forceInferChildren)
						InferArgumentsInBinaryOperator(expr, null, null);
					return typeSystem.Boolean;
				case ILCode.Clt:
				case ILCode.Cgt:
					if (forceInferChildren)
						InferArgumentsInBinaryOperator(expr, true, null);
					return typeSystem.Boolean;
				case ILCode.Clt_Un:
				case ILCode.Cgt_Un:
					if (forceInferChildren)
						InferArgumentsInBinaryOperator(expr, false, null);
					return typeSystem.Boolean;
					#endregion
					#region Branch instructions
				case ILCode.Brtrue:
					if (forceInferChildren)
						InferTypeForExpression(expr.Arguments.Single(), typeSystem.Boolean);
					return null;
				case ILCode.Br:
				case ILCode.Leave:
				case ILCode.Endfinally:
				case ILCode.Switch:
				case ILCode.Throw:
				case ILCode.Rethrow:
				case ILCode.LoopOrSwitchBreak:
				case ILCode.LoopContinue:
				case ILCode.YieldBreak:
					return null;
				case ILCode.Ret:
					if (forceInferChildren && expr.Arguments.Count == 1)
						InferTypeForExpression(expr.Arguments[0], context.CurrentMethod.ReturnType);
					return null;
				case ILCode.YieldReturn:
					if (forceInferChildren) {
						GenericInstanceType genericType = context.CurrentMethod.ReturnType as GenericInstanceType;
						if (genericType != null) { // IEnumerable<T> or IEnumerator<T>
							InferTypeForExpression(expr.Arguments[0], genericType.GenericArguments[0]);
						} else { // non-generic IEnumerable or IEnumerator
							InferTypeForExpression(expr.Arguments[0], typeSystem.Object);
						}
					}
					return null;
					#endregion
				case ILCode.Pop:
					return null;
				case ILCode.Dup:
					return InferTypeForExpression(expr.Arguments.Single(), expectedType);
				default:
					Debug.WriteLine("Type Inference: Can't handle " + expr.Code.GetName());
					return null;
			}
		}
 private StaticByRefTypeWrapper MakeByRefType(ByReferenceType referenceTypeHandle)
 {
     return MakeType(referenceTypeHandle.ElementType).MakeByRefType();
 }
        protected override bool VerifyIsConstrainedToNSObject(TypeReference type, out TypeReference constrained_type)
        {
            constrained_type = null;

            var gp = type as GenericParameter;
            if (gp != null) {
                if (!gp.HasConstraints)
                    return false;
                foreach (var c in gp.Constraints) {
                    if (IsNSObject (c)) {
                        constrained_type = c;
                        return true;
                    }
                }
                return false;
            }

            var git = type as GenericInstanceType;
            if (git != null) {
                var rv = true;
                if (git.HasGenericArguments) {
                    var newGit = new GenericInstanceType (git.ElementType);
                    for (int i = 0; i < git.GenericArguments.Count; i++) {
                        TypeReference constr;
                        rv &= VerifyIsConstrainedToNSObject (git.GenericArguments [i], out constr);
                        newGit.GenericArguments.Add (constr ?? git.GenericArguments [i]);
                    }
                    constrained_type = newGit;
                }
                return rv;
            }

            var el = type as ArrayType;
            if (el != null) {
                var rv = VerifyIsConstrainedToNSObject (el.ElementType, out constrained_type);
                if (constrained_type == null)
                    return rv;
                constrained_type = new ArrayType (constrained_type, el.Rank);
                return rv;
            }

            var rt = type as ByReferenceType;
            if (rt != null) {
                var rv = VerifyIsConstrainedToNSObject (rt.ElementType, out constrained_type);
                if (constrained_type == null)
                    return rv;
                constrained_type = new ByReferenceType (constrained_type);
                return rv;
            }

            var tr = type as PointerType;
            if (tr != null) {
                var rv = VerifyIsConstrainedToNSObject (tr.ElementType, out constrained_type);
                if (constrained_type == null)
                    return rv;
                constrained_type = new PointerType (constrained_type);
                return rv;
            }

            return true;
        }
 protected virtual ByReferenceType updateByReferenceType(ByReferenceType a)
 {
     return new ByReferenceType(update(a.ElementType));
 }
Beispiel #34
0
 void doByReferenceType(ByReferenceType byReferenceType)
 {
     bool present;
     if (byReferenceTypes.TryGetValue(byReferenceType, out present))
         return;
     byReferenceTypes[byReferenceType] = true;
     addByReferenceType(byReferenceType);
 }
Beispiel #35
0
 static int byReferenceTypeHashCode(ByReferenceType a)
 {
     if (a == null)
         return 0;
     return typeSpecificationHashCode(a);
 }
Beispiel #36
0
 public static ByReferenceType ChangeByReferenceType(this ByReferenceType type, TypeReference elementType)
 {
     if (elementType != type.ElementType)
     {
         var result = new ByReferenceType(elementType);
         if (type.HasGenericParameters)
             SetGenericParameters(result, type.GenericParameters);
         return result;
     }
     return type;
 }
 private static ByReferenceType ResolveIfNeeded(IGenericInstance genericInstanceMethod, IGenericInstance genericInstanceType, ByReferenceType byReferenceType)
 {
     return new ByReferenceType(ResolveIfNeeded(genericInstanceMethod, genericInstanceType, byReferenceType.ElementType));
 }