Inheritance: IKVM.Reflection.MemberInfo, IGenericContext, IGenericBinder
Example #1
0
		public override object Read(Type useType, object value, ProtoReader source)
        {
            Helpers.DebugAssert(value != null);
            object newValue = Tail.Read(useType, (Tail.RequiresOldValue ? field.GetValue(value) : null), source);
            if(newValue != null) field.SetValue(value,newValue);
            return null;
        }
 public ConversationWrapper(Conversion conv, Operand op, Type @from, Type to)
 {
     _conv = conv;
     _op = op;
     _to = to;
     _from = @from;
 }
        public ArrayDecorator(TypeModel model, IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, Type arrayType, bool overwriteList, bool supportNull)
            : base(tail)
        {
            Helpers.DebugAssert(arrayType != null, "arrayType should be non-null");
            Helpers.DebugAssert(arrayType.IsArray && arrayType.GetArrayRank() == 1, "should be single-dimension array; " + arrayType.FullName);
            this.itemType = arrayType.GetElementType();
#if NO_GENERICS
            Type underlyingItemType = itemType;
#else
            Type underlyingItemType = supportNull ? itemType : (Helpers.GetUnderlyingType(itemType) ?? itemType);
#endif

            Helpers.DebugAssert(underlyingItemType == Tail.ExpectedType, "invalid tail");
            Helpers.DebugAssert(Tail.ExpectedType != model.MapType(typeof(byte)), "Should have used BlobSerializer");
            if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0) throw new ArgumentOutOfRangeException("fieldNumber");
            if (!ListDecorator.CanPack(packedWireType))
            {
                if (writePacked) throw new InvalidOperationException("Only simple data-types can use packed encoding");
                packedWireType = WireType.None;
            }       
            this.fieldNumber = fieldNumber;
            this.packedWireType = packedWireType;
            if (writePacked) options |= OPTIONS_WritePacked;
            if (overwriteList) options |= OPTIONS_OverwriteList;
            if (supportNull) options |= OPTIONS_SupportNull;
            this.arrayType = arrayType;
        }
Example #4
0
 public static AttributeMap[] Create(TypeModel model, Type type, bool inherit)
 {
     #if FEAT_IKVM
     Type attribType = model.MapType(typeof(System.Attribute));
     System.Collections.Generic.IList<CustomAttributeData> all = type.__GetCustomAttributes(attribType, inherit);
     AttributeMap[] result = new AttributeMap[all.Count];
     int index = 0;
     foreach (CustomAttributeData attrib in all)
     {
         result[index++] = new AttributeDataMap(attrib);
     }
     return result;
     #else
     #if WINRT
     Attribute[] all = System.Linq.Enumerable.ToArray(type.GetTypeInfo().GetCustomAttributes(inherit));
     #else
     var all = type.GetCustomAttributes(inherit);
     #endif
     var result = new AttributeMap[all.Length];
     for (var i = 0; i < all.Length; i++)
     {
         result[i] = new ReflectionAttributeMap((Attribute) all[i]);
     }
     return result;
     #endif
 }
Example #5
0
		public NewDelegate(Type delegateType, Operand target, string methodName, ITypeMapper typeMapper)
		{
			_delegateType = delegateType;
			_target = target;
		    _typeMapper = typeMapper;
		    Initialize(target.GetReturnType(typeMapper), methodName);
		}
Example #6
0
 public NetObjectSerializer(TypeModel model, Type type, int key, BclHelpers.NetObjectOptions options)
 {
     bool dynamicType = (options & BclHelpers.NetObjectOptions.DynamicType) != 0;
     this.key = dynamicType ? -1 : key;
     this.type = dynamicType ? model.MapType(typeof (object)) : type;
     this.options = options;
 }
Example #7
0
 public SafeCast(Operand op, Type t)
 {
     _op = op;
     _t = t;
     if (t.IsValueType)
         _conditional = _op.Is(_t).Conditional(_op.Cast(_t), new DefaultValue(_t));
 }
		public override void Write(Type useType, object value, ProtoWriter dest)
        {
            if(getSpecified == null || (bool)getSpecified.Invoke(value, null))
            {
                Tail.Write(useType, value, dest);
            }
        }
 internal static FieldInfo GetClassLiteralField(Type type)
 {
     Debug.Assert(type != Types.Void);
     if (classLiteralType == null)
     {
     #if STATIC_COMPILER
         classLiteralType = JVM.CoreAssembly.GetType("ikvm.internal.ClassLiteral`1");
     #elif !FIRST_PASS
         classLiteralType = typeof([email protected]<>);
     #endif
     }
     #if !STATIC_COMPILER
     if (!IsTypeBuilder(type))
     {
         return classLiteralType.MakeGenericType(type).GetField("Value", BindingFlags.Public | BindingFlags.Static);
     }
     #endif
     if (classLiteralField == null)
     {
         classLiteralField = classLiteralType.GetField("Value", BindingFlags.Public | BindingFlags.Static);
     }
     #if !NOEMIT
     return TypeBuilder.GetField(classLiteralType.MakeGenericType(type), classLiteralField);
     #else
     return null;
     #endif
 }
        private void EmitBeq(Compiler.CompilerContext ctx, Compiler.CodeLabel label, Type type)
        {
            switch (Helpers.GetTypeCode(type))
            {
                case ProtoTypeCode.Boolean:
                case ProtoTypeCode.Byte:
                case ProtoTypeCode.Char:
                case ProtoTypeCode.Double:
                case ProtoTypeCode.Int16:
                case ProtoTypeCode.Int32:
                case ProtoTypeCode.Int64:
                case ProtoTypeCode.SByte:
                case ProtoTypeCode.Single:
                case ProtoTypeCode.UInt16:
                case ProtoTypeCode.UInt32:
                case ProtoTypeCode.UInt64:
                    ctx.BranchIfEqual(label, false);
                    break;

                default:
                    MethodInfo method = type.GetMethod("op_Equality", BindingFlags.Public | BindingFlags.Static,
                        null, new Type[] { type, type}, null);
                    if (method == null || method.ReturnType != ctx.MapType(typeof(bool)))
                    {
                        throw new InvalidOperationException("No suitable equality operator found for default-values of type: " + type.FullName);
                    }
                    ctx.EmitCall(method);
                    ctx.BranchIfTrue(label, false);
                    break;
            }
        }
Example #11
0
 public FieldDecorator(Type forType, FieldInfo field, IProtoSerializer tail) : base(tail)
 {
     Helpers.DebugAssert(forType != null);
     Helpers.DebugAssert(field != null);
     this.forType = forType;
     this.field = field;
 }
        static Type ResolveIReadOnlyCollection(Type declaredType, Type t)
        {
#if WINRT
            foreach (Type intImplBasic in declaredType.GetTypeInfo().ImplementedInterfaces)
            {
                TypeInfo intImpl = intImplBasic.GetTypeInfo();
                if (intImpl.IsGenericType && intImpl.Name.StartsWith("IReadOnlyCollection`"))
                {
                    if(t != null)
                    {
                        Type[] typeArgs = intImpl.GenericTypeArguments;
                        if (typeArgs.Length != 1 && typeArgs[0] != t) continue;
                    }
                    return intImplBasic;
                }
            }
#else
            foreach (Type intImpl in declaredType.GetInterfaces())
            {
                if (intImpl.IsGenericType && intImpl.Name.StartsWith("IReadOnlyCollection`"))
                {
                    if(t != null)
                    {
                        Type[] typeArgs = intImpl.GetGenericArguments();
                        if (typeArgs.Length != 1 && typeArgs[0] != t) continue;
                    }
                    return intImpl;
                }
            }
#endif
            return null;
        }
Example #13
0
        public override object Read(Type useType, object value, ProtoReader source)
        {
            Helpers.DebugAssert(fieldNumber == source.FieldNumber);
            if (strict) { source.Assert(wireType); }
            else if (NeedsHint) { source.Hint(wireType); }
			return Tail.Read(useType,value, source);
        }
Example #14
0
	    internal EventGen(TypeGen owner, string name, Type type, MethodAttributes mthAttr)
		{
			_owner = owner;
			Name = name;
			_type = type;
			_attrs = mthAttr;
		}
        private static bool HasCast(Type type, Type from, Type to, out MethodInfo op)
        {
#if WINRT
            System.Collections.Generic.List<MethodInfo> list = new System.Collections.Generic.List<MethodInfo>();
            foreach (var item in type.GetRuntimeMethods())
            {
                if (item.IsStatic) list.Add(item);
            }
            MethodInfo[] found = list.ToArray();
#else
            const BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
            MethodInfo[] found = type.GetMethods(flags);
#endif
            for(int i = 0 ; i < found.Length ; i++)
            {
                MethodInfo m = found[i];
                if ((m.Name != "op_Implicit" && m.Name != "op_Explicit") || m.ReturnType != to)
                {
                    continue;
                }
                ParameterInfo[] paramTypes = m.GetParameters();
                if(paramTypes.Length == 1 && paramTypes[0].ParameterType == from)
                {
                    op = m;
                    return true;
                }
            }
            op = null;
            return false;
        }
		internal static bool IsReflectionOnly(Type type)
		{
			while (type.HasElementType)
			{
				type = type.GetElementType();
			}
			Assembly asm = type.Assembly;
			if (asm != null && asm.ReflectionOnly)
			{
				return true;
			}
			if (!type.IsGenericType || type.IsGenericTypeDefinition)
			{
				return false;
			}
			// we have a generic type instantiation, it might have ReflectionOnly type arguments
			foreach (Type arg in type.GetGenericArguments())
			{
				if (IsReflectionOnly(arg))
				{
					return true;
				}
			}
			return false;
		}
Example #17
0
		public override void Write(Type useType, object value, ProtoWriter dest)
        {
            if (!object.Equals(value, defaultValue))
            {
                Tail.Write(useType, value, dest);
            }
        }
        public static ParseableSerializer TryCreate(Type type, TypeModel model)
        {
            if (type == null) throw new ArgumentNullException("type");
#if WINRT || PORTABLE || COREFX
            MethodInfo method = null;
            
#if WINRT || COREFX
            foreach (MethodInfo tmp in type.GetTypeInfo().GetDeclaredMethods("Parse"))
#else
            foreach (MethodInfo tmp in type.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly))
#endif
            {
                ParameterInfo[] p;
                if (tmp.Name == "Parse" && tmp.IsPublic && tmp.IsStatic && tmp.DeclaringType == type && (p = tmp.GetParameters()) != null && p.Length == 1 && p[0].ParameterType == typeof(string))
                {
                    method = tmp;
                    break;
                }
            }
#else
            MethodInfo method = type.GetMethod("Parse",
                BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly,
                null, new Type[] { model.MapType(typeof(string)) }, null);
#endif
            if (method != null && method.ReturnType == type)
            {
                if (Helpers.IsValueType(type))
                {
                    MethodInfo toString = GetCustomToString(type);
                    if (toString == null || toString.ReturnType != model.MapType(typeof(string))) return null; // need custom ToString, fools
                }
                return new ParseableSerializer(method);
            }
            return null;
        }
Example #19
0
		internal PropertyGen(TypeGen owner, MethodAttributes attrs, Type type, string name)
		{
			_owner = owner;
			_attrs = attrs;
			_type = type;
			Name = name;
		    _indexParameters = new ParameterGenCollection(owner.TypeMapper);
		}
Example #20
0
            public EnumPair(int wireValue, object raw, Type type)
            {
                WireValue = wireValue;
                RawValue = raw;
#if !FEAT_IKVM
                TypedValue = (Enum)Enum.ToObject(type, raw);
#endif
            }
Example #21
0
 internal static bool CanOwnDynamicMethod(Type type)
 {
     return type != null
         && !type.IsInterface
         && !type.HasElementType
         && !type.IsGenericTypeDefinition
         && !type.IsGenericParameter;
 }
Example #22
0
        /// <summary>
        /// 是否是空标签
        /// </summary>
        public bool IsNoAttribute(Type infoType)
        {
            if (TypeIsNoAttribute.ContainsKey(infoType))
            {
                return TypeIsNoAttribute[infoType];
            }

            return false;
        }
 void AppendTypeNameNoOuter(StringBuilder sb, Type type)
 {
     if (type.__Namespace != null)
     {
         sb.Append(QuoteIdentifier(type.__Namespace));
         sb.Append('.');
     }
     sb.Append(QuoteIdentifier(type.__Name));
 }
 void AppendTypeName(StringBuilder sb, Type type)
 {
     if (type.IsNested)
     {
         AppendTypeName(sb, type.DeclaringType);
         sb.Append('/');
     }
     AppendTypeNameNoOuter(sb, type);
 }
Example #25
0
 public PropertyDecorator(TypeModel model, Type forType, PropertyInfo property, IProtoSerializer tail) : base(tail)
 {
     Helpers.DebugAssert(forType != null);
     Helpers.DebugAssert(property != null);
     this.forType = forType;
     this.property = property;
     SanityCheck(model, property, tail, out readOptionsWriteValue, true, true);
     shadowSetter = GetShadowSetter(model, property);
 }
Example #26
0
		internal FieldGen(TypeGen owner, string name, Type type, FieldAttributes attrs)
		{
			_owner = owner;
			_attrs = attrs;
			Name = name;
			_type = type;

			_fb = owner.TypeBuilder.DefineField(name, type, attrs);
			owner.RegisterForCompletion(this);
		}
Example #27
0
        private static bool HasCast(TypeModel model, Type type, Type from, Type to, out MethodInfo op)
        {
#if WINRT
            System.Collections.Generic.List<MethodInfo> list = new System.Collections.Generic.List<MethodInfo>();
            foreach (var item in type.GetRuntimeMethods())
            {
                if (item.IsStatic) list.Add(item);
            }
            MethodInfo[] found = list.ToArray();
#else
            const BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
            MethodInfo[] found = type.GetMethods(flags);
#endif
            ParameterInfo[] paramTypes;
            Type convertAttributeType = null;
            for (int i = 0; i < found.Length; i++)
            {
                MethodInfo m = found[i];
                if (m.ReturnType != to) continue;
                paramTypes = m.GetParameters();
                if(paramTypes.Length == 1 && paramTypes[0].ParameterType == from)
                {
                    if (convertAttributeType == null)
                    {
                        convertAttributeType = model.MapType(typeof(ProtoConverterAttribute), false);
                        if (convertAttributeType == null)
                        { // attribute isn't defined in the source assembly: stop looking
                            break;
                        }
                    }
                    if (m.IsDefined(convertAttributeType, true))
                    {
                        op = m;
                        return true;
                    }
                }
            }

            for(int i = 0 ; i < found.Length ; i++)
            {
                MethodInfo m = found[i];
                if ((m.Name != "op_Implicit" && m.Name != "op_Explicit") || m.ReturnType != to)
                {
                    continue;
                }
                paramTypes = m.GetParameters();
                if(paramTypes.Length == 1 && paramTypes[0].ParameterType == from)
                {
                    op = m;
                    return true;
                }
            }
            op = null;
            return false;
        }
Example #28
0
        private DotNetTypeWrapper(Type type, string name)
            : base(TypeFlags.None, GetModifiers(type), name)
        {
            Debug.Assert(!(type.IsByRef), type.FullName);
            Debug.Assert(!(type.IsPointer), type.FullName);
            Debug.Assert(!(type.Name.EndsWith("[]")), type.FullName);
            Debug.Assert(!(type is TypeBuilder), type.FullName);
            Debug.Assert(!(AttributeHelper.IsJavaModule(type.Module)));

            this.type = type;
        }
Example #29
0
 static MethodHandleUtil()
 {
     #if STATIC_COMPILER
     typeofMHA = StaticCompiler.GetRuntimeType("IKVM.Runtime.MHA`8");
     typeofMHV = new Type[] {
         StaticCompiler.GetRuntimeType("IKVM.Runtime.MHV"),
         StaticCompiler.GetRuntimeType("IKVM.Runtime.MHV`1"),
         StaticCompiler.GetRuntimeType("IKVM.Runtime.MHV`2"),
         StaticCompiler.GetRuntimeType("IKVM.Runtime.MHV`3"),
         StaticCompiler.GetRuntimeType("IKVM.Runtime.MHV`4"),
         StaticCompiler.GetRuntimeType("IKVM.Runtime.MHV`5"),
         StaticCompiler.GetRuntimeType("IKVM.Runtime.MHV`6"),
         StaticCompiler.GetRuntimeType("IKVM.Runtime.MHV`7"),
         StaticCompiler.GetRuntimeType("IKVM.Runtime.MHV`8"),
     };
     typeofMH = new Type[] {
         null,
         StaticCompiler.GetRuntimeType("IKVM.Runtime.MH`1"),
         StaticCompiler.GetRuntimeType("IKVM.Runtime.MH`2"),
         StaticCompiler.GetRuntimeType("IKVM.Runtime.MH`3"),
         StaticCompiler.GetRuntimeType("IKVM.Runtime.MH`4"),
         StaticCompiler.GetRuntimeType("IKVM.Runtime.MH`5"),
         StaticCompiler.GetRuntimeType("IKVM.Runtime.MH`6"),
         StaticCompiler.GetRuntimeType("IKVM.Runtime.MH`7"),
         StaticCompiler.GetRuntimeType("IKVM.Runtime.MH`8"),
         StaticCompiler.GetRuntimeType("IKVM.Runtime.MH`9"),
     };
     #else
     typeofMHA = typeof(IKVM.Runtime.MHA<,,,,,,,>);
     typeofMHV = new Type[] {
         typeof(IKVM.Runtime.MHV),
         typeof(IKVM.Runtime.MHV<>),
         typeof(IKVM.Runtime.MHV<,>),
         typeof(IKVM.Runtime.MHV<,,>),
         typeof(IKVM.Runtime.MHV<,,,>),
         typeof(IKVM.Runtime.MHV<,,,,>),
         typeof(IKVM.Runtime.MHV<,,,,,>),
         typeof(IKVM.Runtime.MHV<,,,,,,>),
         typeof(IKVM.Runtime.MHV<,,,,,,,>),
     };
     typeofMH = new Type[] {
         null,
         typeof(IKVM.Runtime.MH<>),
         typeof(IKVM.Runtime.MH<,>),
         typeof(IKVM.Runtime.MH<,,>),
         typeof(IKVM.Runtime.MH<,,,>),
         typeof(IKVM.Runtime.MH<,,,,>),
         typeof(IKVM.Runtime.MH<,,,,,>),
         typeof(IKVM.Runtime.MH<,,,,,,>),
         typeof(IKVM.Runtime.MH<,,,,,,,>),
         typeof(IKVM.Runtime.MH<,,,,,,,,>),
     };
     #endif
 }
		internal static void Create(ModuleBuilder modb, ClassLoaderWrapper loader)
		{
			TypeBuilder tb = modb.DefineType(DotNetTypeWrapper.GenericDelegateInterfaceTypeName, TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.Public);
			tb.DefineGenericParameters("T")[0].SetBaseTypeConstraint(Types.MulticastDelegate);
			genericDelegateInterfaceType = tb.CreateType();

			genericAttributeAnnotationType = CreateAnnotationType(modb, DotNetTypeWrapper.GenericAttributeAnnotationTypeName);
			genericAttributeAnnotationMultipleType = CreateAnnotationType(modb, DotNetTypeWrapper.GenericAttributeAnnotationMultipleTypeName);
			genericAttributeAnnotationReturnValueType = CreateAnnotationType(modb, DotNetTypeWrapper.GenericAttributeAnnotationReturnValueTypeName);
			CreateEnumEnum(modb, loader);
		}
Example #31
0
 public static bool Is(this IKVM.Reflection.Type self, string @namespace, string name)
 {
     return((self.Namespace == @namespace) && (self.Name == name));
 }
Example #32
0
        public void EmitRead(Compiler.CompilerContext ctx, Compiler.Local incoming)
        {
            using (Compiler.Local objValue = ctx.GetLocalWithValue(ExpectedType, incoming))
            {
                Compiler.Local[] locals = new Compiler.Local[members.Length];
                try
                {
                    for (int i = 0; i < locals.Length; i++)
                    {
                        Type type  = GetMemberType(i);
                        bool store = true;
                        locals[i] = new Compiler.Local(ctx, type);
                        if (!Helpers.IsValueType(ExpectedType))
                        {
                            // value-types always read the old value
                            if (Helpers.IsValueType(type))
                            {
                                switch (Helpers.GetTypeCode(type))
                                {
                                case ProtoTypeCode.Boolean:
                                case ProtoTypeCode.Byte:
                                case ProtoTypeCode.Int16:
                                case ProtoTypeCode.Int32:
                                case ProtoTypeCode.SByte:
                                case ProtoTypeCode.UInt16:
                                case ProtoTypeCode.UInt32:
                                    ctx.LoadValue(0);
                                    break;

                                case ProtoTypeCode.Int64:
                                case ProtoTypeCode.UInt64:
                                    ctx.LoadValue(0L);
                                    break;

                                case ProtoTypeCode.Single:
                                    ctx.LoadValue(0.0F);
                                    break;

                                case ProtoTypeCode.Double:
                                    ctx.LoadValue(0.0D);
                                    break;

                                case ProtoTypeCode.Decimal:
                                    ctx.LoadValue(0M);
                                    break;

                                case ProtoTypeCode.Guid:
                                    ctx.LoadValue(Guid.Empty);
                                    break;

                                default:
                                    ctx.LoadAddress(locals[i], type);
                                    ctx.EmitCtor(type);
                                    store = false;
                                    break;
                                }
                            }
                            else
                            {
                                ctx.LoadNullRef();
                            }
                            if (store)
                            {
                                ctx.StoreValue(locals[i]);
                            }
                        }
                    }

                    Compiler.CodeLabel skipOld = Helpers.IsValueType(ExpectedType)
                                                        ? new Compiler.CodeLabel()
                                                        : ctx.DefineLabel();
                    if (!Helpers.IsValueType(ExpectedType))
                    {
                        ctx.LoadAddress(objValue, ExpectedType);
                        ctx.BranchIfFalse(skipOld, false);
                    }
                    for (int i = 0; i < members.Length; i++)
                    {
                        ctx.LoadAddress(objValue, ExpectedType);
                        if (members[i] is FieldInfo)
                        {
                            ctx.LoadValue((FieldInfo)members[i]);
                        }
                        else if (members[i] is PropertyInfo)
                        {
                            ctx.LoadValue((PropertyInfo)members[i]);
                        }
                        ctx.StoreValue(locals[i]);
                    }

                    if (!Helpers.IsValueType(ExpectedType))
                    {
                        ctx.MarkLabel(skipOld);
                    }

                    using (Compiler.Local fieldNumber = new Compiler.Local(ctx, ctx.MapType(typeof(int))))
                    {
                        Compiler.CodeLabel @continue     = ctx.DefineLabel(),
                                           processField  = ctx.DefineLabel(),
                                           notRecognised = ctx.DefineLabel();
                        ctx.Branch(@continue, false);

                        Compiler.CodeLabel[] handlers = new Compiler.CodeLabel[members.Length];
                        for (int i = 0; i < members.Length; i++)
                        {
                            handlers[i] = ctx.DefineLabel();
                        }

                        ctx.MarkLabel(processField);

                        ctx.LoadValue(fieldNumber);
                        ctx.LoadValue(1);
                        ctx.Subtract(); // jump-table is zero-based
                        ctx.Switch(handlers);

                        // and the default:
                        ctx.Branch(notRecognised, false);
                        for (int i = 0; i < handlers.Length; i++)
                        {
                            ctx.MarkLabel(handlers[i]);
                            IProtoSerializer tail           = tails[i];
                            Compiler.Local   oldValIfNeeded = tail.RequiresOldValue ? locals[i] : null;
                            ctx.ReadNullCheckedTail(locals[i].Type, tail, oldValIfNeeded);
                            if (tail.ReturnsValue)
                            {
                                if (Helpers.IsValueType(locals[i].Type))
                                {
                                    ctx.StoreValue(locals[i]);
                                }
                                else
                                {
                                    Compiler.CodeLabel hasValue = ctx.DefineLabel(), allDone = ctx.DefineLabel();

                                    ctx.CopyValue();
                                    ctx.BranchIfTrue(hasValue, true); // interpret null as "don't assign"
                                    ctx.DiscardValue();
                                    ctx.Branch(allDone, true);
                                    ctx.MarkLabel(hasValue);
                                    ctx.StoreValue(locals[i]);
                                    ctx.MarkLabel(allDone);
                                }
                            }
                            ctx.Branch(@continue, false);
                        }

                        ctx.MarkLabel(notRecognised);
                        ctx.LoadReaderWriter();
                        ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("SkipField"));

                        ctx.MarkLabel(@continue);
                        ctx.EmitBasicRead("ReadFieldHeader", ctx.MapType(typeof(int)));
                        ctx.CopyValue();
                        ctx.StoreValue(fieldNumber);
                        ctx.LoadValue(0);
                        ctx.BranchIfGreater(processField, false);
                    }
                    for (int i = 0; i < locals.Length; i++)
                    {
                        ctx.LoadValue(locals[i]);
                    }

                    ctx.EmitCtor(ctor);
                    ctx.StoreValue(objValue);
                }
                finally
                {
                    for (int i = 0; i < locals.Length; i++)
                    {
                        if (locals[i] != null)
                        {
                            locals[i].Dispose(); // release for re-use
                        }
                    }
                }
            }
        }
Example #33
0
        protected MethodInfo GetEnumeratorInfo(TypeModel model, out MethodInfo moveNext, out MethodInfo current)
        {
#if WINRT || COREFX
            TypeInfo enumeratorType = null, iteratorType, expectedType = ExpectedType.GetTypeInfo();
#else
            Type enumeratorType = null, iteratorType, expectedType = ExpectedType;
#endif

            // try a custom enumerator
            MethodInfo getEnumerator = Helpers.GetInstanceMethod(expectedType, "GetEnumerator", null);
            Type       itemType      = Tail.ExpectedType;

            Type getReturnType = null;
            if (getEnumerator != null)
            {
                getReturnType = getEnumerator.ReturnType;
                iteratorType  = getReturnType
#if WINRT || COREFX || COREFX
                                .GetTypeInfo()
#endif
                ;
                moveNext = Helpers.GetInstanceMethod(iteratorType, "MoveNext", null);
                PropertyInfo prop = Helpers.GetProperty(iteratorType, "Current", false);
                current = prop == null ? null : Helpers.GetGetMethod(prop, false, false);
                if (moveNext == null && (model.MapType(ienumeratorType).IsAssignableFrom(iteratorType)))
                {
                    moveNext = Helpers.GetInstanceMethod(model.MapType(ienumeratorType), "MoveNext", null);
                }
                // fully typed
                if (moveNext != null && moveNext.ReturnType == model.MapType(typeof(bool)) &&
                    current != null && current.ReturnType == itemType)
                {
                    return(getEnumerator);
                }
                moveNext = current = getEnumerator = null;
            }

#if !NO_GENERICS
            // try IEnumerable<T>
            Type tmp = model.MapType(typeof(System.Collections.Generic.IEnumerable <>), false);

            if (tmp != null)
            {
                tmp = tmp.MakeGenericType(itemType);

#if WINRT || COREFX
                enumeratorType = tmp.GetTypeInfo();
#else
                enumeratorType = tmp;
#endif
            }
            ;
            if (enumeratorType != null && enumeratorType.IsAssignableFrom(expectedType))
            {
                getEnumerator = Helpers.GetInstanceMethod(enumeratorType, "GetEnumerator");
                getReturnType = getEnumerator.ReturnType;

#if WINRT || COREFX
                iteratorType = getReturnType.GetTypeInfo();
#else
                iteratorType = getReturnType;
#endif

                moveNext = Helpers.GetInstanceMethod(model.MapType(ienumeratorType), "MoveNext");
                current  = Helpers.GetGetMethod(Helpers.GetProperty(iteratorType, "Current", false), false, false);
                return(getEnumerator);
            }
#endif
            // give up and fall-back to non-generic IEnumerable
            enumeratorType = model.MapType(ienumerableType);
            getEnumerator  = Helpers.GetInstanceMethod(enumeratorType, "GetEnumerator");
            getReturnType  = getEnumerator.ReturnType;
            iteratorType   = getReturnType
#if WINRT || COREFX
                             .GetTypeInfo()
#endif
            ;
            moveNext = Helpers.GetInstanceMethod(iteratorType, "MoveNext");
            current  = Helpers.GetGetMethod(Helpers.GetProperty(iteratorType, "Current", false), false, false);
            return(getEnumerator);
        }
Example #34
0
        protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            using (Compiler.Local oldList = AppendToCollection ? ctx.GetLocalWithValue(ExpectedType, valueFrom) : null)
                using (Compiler.Local builder = new Compiler.Local(ctx, builderFactory.ReturnType))
                {
                    ctx.EmitCall(builderFactory);
                    ctx.StoreValue(builder);

                    if (AppendToCollection)
                    {
                        Compiler.CodeLabel done = ctx.DefineLabel();
                        if (!ExpectedType.IsValueType)
                        {
                            ctx.LoadValue(oldList);
                            ctx.BranchIfFalse(done, false); // old value null; nothing to add
                        }
                        PropertyInfo prop = Helpers.GetProperty(ExpectedType, "Length", false);
                        if (prop == null)
                        {
                            prop = Helpers.GetProperty(ExpectedType, "Count", false);
                        }
#if !NO_GENERICS
                        if (prop == null)
                        {
                            prop = Helpers.GetProperty(ResolveIReadOnlyCollection(ExpectedType, Tail.ExpectedType), "Count", false);
                        }
#endif
                        ctx.LoadAddress(oldList, oldList.Type);
                        ctx.EmitCall(Helpers.GetGetMethod(prop, false, false));
                        ctx.BranchIfFalse(done, false); // old list is empty; nothing to add

                        Type voidType = ctx.MapType(typeof(void));
                        if (addRange != null)
                        {
                            ctx.LoadValue(builder);
                            ctx.LoadValue(oldList);
                            ctx.EmitCall(addRange);
                            if (addRange.ReturnType != null && add.ReturnType != voidType)
                            {
                                ctx.DiscardValue();
                            }
                        }
                        else
                        {
                            // loop and call Add repeatedly
                            MethodInfo moveNext, current, getEnumerator = GetEnumeratorInfo(ctx.Model, out moveNext, out current);
                            Helpers.DebugAssert(moveNext != null);
                            Helpers.DebugAssert(current != null);
                            Helpers.DebugAssert(getEnumerator != null);

                            Type enumeratorType = getEnumerator.ReturnType;
                            using (Compiler.Local iter = new Compiler.Local(ctx, enumeratorType))
                            {
                                ctx.LoadAddress(oldList, ExpectedType);
                                ctx.EmitCall(getEnumerator);
                                ctx.StoreValue(iter);
                                using (ctx.Using(iter))
                                {
                                    Compiler.CodeLabel body = ctx.DefineLabel(), next = ctx.DefineLabel();
                                    ctx.Branch(next, false);

                                    ctx.MarkLabel(body);
                                    ctx.LoadAddress(builder, builder.Type);
                                    ctx.LoadAddress(iter, enumeratorType);
                                    ctx.EmitCall(current);
                                    ctx.EmitCall(add);
                                    if (add.ReturnType != null && add.ReturnType != voidType)
                                    {
                                        ctx.DiscardValue();
                                    }

                                    ctx.MarkLabel(@next);
                                    ctx.LoadAddress(iter, enumeratorType);
                                    ctx.EmitCall(moveNext);
                                    ctx.BranchIfTrue(body, false);
                                }
                            }
                        }


                        ctx.MarkLabel(done);
                    }

                    EmitReadList(ctx, builder, Tail, add, packedWireType, false);

                    ctx.LoadAddress(builder, builder.Type);
                    ctx.EmitCall(finish);
                    if (ExpectedType != finish.ReturnType)
                    {
                        ctx.Cast(ExpectedType);
                    }
                }
        }
        private void WriteFieldHandler(

            Compiler.CompilerContext ctx, Type expected, Compiler.Local loc,

            Compiler.CodeLabel handler, Compiler.CodeLabel @continue, IProtoSerializer serializer)

        {
            ctx.MarkLabel(handler);

            Type serType = serializer.ExpectedType;

            if (serType == forType)
            {
                EmitCreateIfNull(ctx, loc);

                serializer.EmitRead(ctx, loc);
            }

            else
            {
                //RuntimeTypeModel rtm = (RuntimeTypeModel)ctx.Model;

                if (((IProtoTypeSerializer)serializer).CanCreateInstance())

                {
                    Compiler.CodeLabel allDone = ctx.DefineLabel();



                    ctx.LoadValue(loc);

                    ctx.BranchIfFalse(allDone, false); // null is always ok



                    ctx.LoadValue(loc);

                    ctx.TryCast(serType);

                    ctx.BranchIfTrue(allDone, false); // not null, but of the correct type



                    // otherwise, need to convert it

                    ctx.LoadReaderWriter();

                    ctx.LoadValue(loc);

                    ((IProtoTypeSerializer)serializer).EmitCreateInstance(ctx);

                    ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("Merge"));

                    ctx.Cast(expected);

                    ctx.StoreValue(loc); // Merge always returns a value



                    // nothing needs doing

                    ctx.MarkLabel(allDone);
                }

                ctx.LoadValue(loc);

                ctx.Cast(serType);

                serializer.EmitRead(ctx, null);
            }



            if (serializer.ReturnsValue)

            {   // update the variable
                ctx.StoreValue(loc);
            }

            ctx.Branch(@continue, false); // "continue"
        }
        private object InvokeCallback(MethodInfo method, object obj, SerializationContext context)

        {
            object result = null;

            object[] args;

            if (method != null)

            {   // pass in a streaming context if one is needed, else null
                bool handled;

                ParameterInfo[] parameters = method.GetParameters();

                switch (parameters.Length)

                {
                case 0:

                    args = null;

                    handled = true;

                    break;

                default:

                    args = new object[parameters.Length];

                    handled = true;

                    for (int i = 0; i < args.Length; i++)

                    {
                        object val;

                        Type paramType = parameters[i].ParameterType;

                        if (paramType == typeof(SerializationContext))
                        {
                            val = context;
                        }

                        else if (paramType == typeof(System.Type))
                        {
                            val = constructType;
                        }

#if PLAT_BINARYFORMATTER || (SILVERLIGHT && NET_4_0)
                        else if (paramType == typeof(System.Runtime.Serialization.StreamingContext))
                        {
                            val = (System.Runtime.Serialization.StreamingContext)context;
                        }
#endif

                        else

                        {
                            val = null;

                            handled = false;
                        }

                        args[i] = val;
                    }

                    break;
                }

                if (handled)

                {
                    result = method.Invoke(obj, args);
                }

                else

                {
                    throw Meta.CallbackSet.CreateInvalidCallbackSignature(method);
                }
            }

            return(result);
        }
Example #37
0
 public _Local(CodeGen owner, Type t)
 {
     _owner = owner; _t = t;
     _scope = owner.GetBlockForVariable();
 }
Example #38
0
 public _Arg(int index, Type type)
 {
     _index = checked ((ushort)index);
     _type  = type;
 }
Example #39
0
 public _Base(Type type) : base(0, type)
 {
 }
Example #40
0
 public ContextualOperand Local(Type type)
 {
     return(new ContextualOperand(new _Local(this, type), TypeMapper));
 }
Example #41
0
        QualifiedType VisitType(IKVM.Reflection.Type managedType)
        {
            var isString = managedType.HasElementType && IKVM.Reflection.Type.GetTypeCode(
                managedType.GetElementType()) == TypeCode.String;

            if (managedType.IsByRef && isString)
            {
                managedType = managedType.GetElementType();
            }

            // If true type is an array, a pointer, or is passed by reference.
            if (managedType.HasElementType)
            {
                var managedElementType = managedType.GetElementType();
                var elementType        = VisitType(managedElementType);

                if (managedType.IsByRef || managedType.IsPointer)
                {
                    var ptrType = new PointerType(elementType)
                    {
                        Modifier = (Options.GeneratorKind == GeneratorKind.CPlusPlus) ?
                                   PointerType.TypeModifier.LVReference :
                                   PointerType.TypeModifier.Pointer
                    };

                    return(new QualifiedType(ptrType));
                }
                else if (managedType.IsArray)
                {
                    if (elementType.Type.IsClass() || Options.GeneratorKind == GeneratorKind.Java)
                    {
                        return(new QualifiedType(new UnsupportedType {
                            Description = managedType.FullName
                        }));
                    }

                    var array = new ArrayType
                    {
                        SizeType      = ArrayType.ArraySize.Variable,
                        QualifiedType = elementType
                    };

                    return(new QualifiedType(array));
                }

                throw new NotImplementedException();
            }

            if (managedType.IsEnum)
            {
                var @enum = Visit(managedType.GetTypeInfo());
                return(new QualifiedType(new TagType(@enum)));
            }

            CppSharp.AST.Type type       = null;
            TypeQualifiers    qualifiers = new TypeQualifiers();

            switch (IKVM.Reflection.Type.GetTypeCode(managedType))
            {
            case TypeCode.Empty:
                type = new BuiltinType(PrimitiveType.Null);
                break;

            case TypeCode.Object:
            case TypeCode.Decimal:
            case TypeCode.DateTime:
                if (managedType.FullName == "System.Void")
                {
                    type = new BuiltinType(PrimitiveType.Void);
                    break;
                }
                var currentUnit = GetTranslationUnit(CurrentAssembly);
                if (managedType.Assembly.GetName().Name != currentUnit.FileNameWithoutExtension ||
                    managedType.IsGenericType)
                {
                    type = new UnsupportedType {
                        Description = managedType.FullName
                    };
                    break;
                }
                var decl = Visit(managedType.GetTypeInfo());
                type = new TagType(decl);
                break;

            case TypeCode.DBNull:
                type = new UnsupportedType()
                {
                    Description = "DBNull"
                };
                break;

            case TypeCode.Boolean:
                type = new BuiltinType(PrimitiveType.Bool);
                break;

            case TypeCode.Char:
                type = new BuiltinType(PrimitiveType.Char);
                break;

            case TypeCode.SByte:
                type = new BuiltinType(PrimitiveType.SChar);
                break;

            case TypeCode.Byte:
                type = new BuiltinType(PrimitiveType.UChar);
                break;

            case TypeCode.Int16:
                type = new BuiltinType(PrimitiveType.Short);
                break;

            case TypeCode.UInt16:
                type = new BuiltinType(PrimitiveType.UShort);
                break;

            case TypeCode.Int32:
                type = new BuiltinType(PrimitiveType.Int);
                break;

            case TypeCode.UInt32:
                type = new BuiltinType(PrimitiveType.UInt);
                break;

            case TypeCode.Int64:
                type = new BuiltinType(PrimitiveType.Long);
                break;

            case TypeCode.UInt64:
                type = new BuiltinType(PrimitiveType.ULong);
                break;

            case TypeCode.Single:
                type = new BuiltinType(PrimitiveType.Float);
                break;

            case TypeCode.Double:
                type = new BuiltinType(PrimitiveType.Double);
                break;

            case TypeCode.String:
                type = new BuiltinType(PrimitiveType.String);
                break;
            }

            return(new QualifiedType(type, qualifiers));
        }
        public BooleanSerializer(ProtoBuf.Meta.TypeModel model)
        {
#if FEAT_IKVM
            expectedType = model.MapType(typeof(bool));
#endif
        }
        public TypeSerializer(TypeModel model, Type forType, int[] fieldNumbers, IProtoSerializer[] serializers, MethodInfo[] baseCtorCallbacks, bool isRootType, bool useConstructor, CallbackSet callbacks, Type constructType, MethodInfo factory)

        {
            Helpers.DebugAssert(forType != null);

            Helpers.DebugAssert(fieldNumbers != null);

            Helpers.DebugAssert(serializers != null);

            Helpers.DebugAssert(fieldNumbers.Length == serializers.Length);



            Helpers.Sort(fieldNumbers, serializers);

            bool hasSubTypes = false;

            for (int i = 1; i < fieldNumbers.Length; i++)

            {
                if (fieldNumbers[i] == fieldNumbers[i - 1])
                {
                    throw new InvalidOperationException("Duplicate field-number detected; " +

                                                        fieldNumbers[i].ToString() + " on: " + forType.FullName);
                }

                if (!hasSubTypes && serializers[i].ExpectedType != forType)

                {
                    hasSubTypes = true;
                }
            }

            this.forType = forType;

            this.factory = factory;

#if WINRT
            this.typeInfo = forType.GetTypeInfo();
#endif

            if (constructType == null)

            {
                constructType = forType;
            }

            else

            {
#if WINRT
                if (!typeInfo.IsAssignableFrom(constructType.GetTypeInfo()))
#else
                if (!forType.IsAssignableFrom(constructType))
#endif

                {
                    throw new InvalidOperationException(forType.FullName + " cannot be assigned from " + constructType.FullName);
                }
            }

            this.constructType = constructType;

            this.serializers = serializers;

            this.fieldNumbers = fieldNumbers;

            this.callbacks = callbacks;

            this.isRootType = isRootType;

            this.useConstructor = useConstructor;



            if (baseCtorCallbacks != null && baseCtorCallbacks.Length == 0)
            {
                baseCtorCallbacks = null;
            }

            this.baseCtorCallbacks = baseCtorCallbacks;

#if !NO_GENERICS
            if (Helpers.GetUnderlyingType(forType) != null)

            {
                throw new ArgumentException("Cannot create a TypeSerializer for nullable types", "forType");
            }
#endif



#if WINRT
            if (iextensible.IsAssignableFrom(typeInfo))

            {
                if (typeInfo.IsValueType || !isRootType || hasSubTypes)
#else
            if (model.MapType(iextensible).IsAssignableFrom(forType))

            {
                if (forType.IsValueType || !isRootType || hasSubTypes)
#endif

                {
                    throw new NotSupportedException("IExtensible is not supported in structs or classes with inheritance");
                }

                isExtensible = true;
            }

#if WINRT
            TypeInfo constructTypeInfo = constructType.GetTypeInfo();

            hasConstructor = !constructTypeInfo.IsAbstract && Helpers.GetConstructor(constructTypeInfo, Helpers.EmptyTypes, true) != null;
#else
            hasConstructor = !constructType.IsAbstract && Helpers.GetConstructor(constructType, Helpers.EmptyTypes, true) != null;
#endif

            if (constructType != forType && useConstructor && !hasConstructor)

            {
                throw new ArgumentException("The supplied default implementation cannot be created: " + constructType.FullName, "constructType");
            }
        }
Example #44
0
 public _Local(CodeGen owner, LocalBuilder var)
 {
     _owner = owner;
     _var   = var;
     _t     = var.LocalType;
 }
        }                                                            // updates field directly

#if FEAT_COMPILER
        void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)

        {
            Type expected = ExpectedType;

            using (Compiler.Local loc = ctx.GetLocalWithValue(expected, valueFrom))

            {
                // pre-callbacks

                EmitCallbackIfNeeded(ctx, loc, TypeModel.CallbackType.BeforeSerialize);



                Compiler.CodeLabel startFields = ctx.DefineLabel();

                // inheritance

                if (CanHaveInheritance)

                {
                    for (int i = 0; i < serializers.Length; i++)

                    {
                        IProtoSerializer ser = serializers[i];

                        Type serType = ser.ExpectedType;

                        if (serType != forType)

                        {
                            Compiler.CodeLabel ifMatch = ctx.DefineLabel(), nextTest = ctx.DefineLabel();

                            ctx.LoadValue(loc);

                            ctx.TryCast(serType);

                            ctx.CopyValue();

                            ctx.BranchIfTrue(ifMatch, true);

                            ctx.DiscardValue();

                            ctx.Branch(nextTest, true);

                            ctx.MarkLabel(ifMatch);

                            ser.EmitWrite(ctx, null);

                            ctx.Branch(startFields, false);

                            ctx.MarkLabel(nextTest);
                        }
                    }



                    if (constructType != null && constructType != forType)

                    {
                        using (Compiler.Local actualType = new Compiler.Local(ctx, ctx.MapType(typeof(System.Type))))

                        {
                            // would have jumped to "fields" if an expected sub-type, so two options:

                            // a: *exactly* that type, b: an *unexpected* type

                            ctx.LoadValue(loc);

                            ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType"));

                            ctx.CopyValue();

                            ctx.StoreValue(actualType);

                            ctx.LoadValue(forType);

                            ctx.BranchIfEqual(startFields, true);



                            ctx.LoadValue(actualType);

                            ctx.LoadValue(constructType);

                            ctx.BranchIfEqual(startFields, true);
                        }
                    }

                    else

                    {
                        // would have jumped to "fields" if an expected sub-type, so two options:

                        // a: *exactly* that type, b: an *unexpected* type

                        ctx.LoadValue(loc);

                        ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType"));

                        ctx.LoadValue(forType);

                        ctx.BranchIfEqual(startFields, true);
                    }

                    // unexpected, then... note that this *might* be a proxy, which

                    // is handled by ThrowUnexpectedSubtype

                    ctx.LoadValue(forType);

                    ctx.LoadValue(loc);

                    ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType"));

                    ctx.EmitCall(ctx.MapType(typeof(TypeModel)).GetMethod("ThrowUnexpectedSubtype",

                                                                          BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static));
                }

                // fields



                ctx.MarkLabel(startFields);

                for (int i = 0; i < serializers.Length; i++)

                {
                    IProtoSerializer ser = serializers[i];

                    if (ser.ExpectedType == forType)
                    {
                        ser.EmitWrite(ctx, loc);
                    }
                }



                // extension data

                if (isExtensible)

                {
                    ctx.LoadValue(loc);

                    ctx.LoadReaderWriter();

                    ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("AppendExtensionData"));
                }

                // post-callbacks

                EmitCallbackIfNeeded(ctx, loc, TypeModel.CallbackType.AfterSerialize);
            }
        }
Example #46
0
        string GetInternalTypeName(IKVM.Reflection.Type type)
        {
            // If true type is an array, a pointer, or is passed by reference.
            if (type.HasElementType)
            {
                var elementType = type.GetElementType();

                if (type.IsArray)
                {
                    return(GetInternalTypeName(elementType) + "[]");
                }

                return(GetInternalTypeName(elementType));
            }

            if (type.IsEnum)
            {
                return(type.FullName);
            }

            switch (IKVM.Reflection.Type.GetTypeCode(type))
            {
            case TypeCode.Object:
                if (type.FullName == "System.IntPtr")
                {
                    return("intptr");
                }
                if (type.FullName == "System.UIntPtr")
                {
                    return("uintptr");
                }
                if (type.FullName == "System.Object")
                {
                    return("object");
                }
                return(type.FullName);

            case TypeCode.Boolean:
                return("bool");

            case TypeCode.Char:
                return("char");

            case TypeCode.SByte:
                return("sbyte");

            case TypeCode.Byte:
                return("byte");

            case TypeCode.Int16:
                return("int16");

            case TypeCode.UInt16:
                return("uint16");

            case TypeCode.Int32:
                return("int");

            case TypeCode.UInt32:
                return("uint");

            case TypeCode.Int64:
                return("long");

            case TypeCode.UInt64:
                return("ulong");

            case TypeCode.Single:
                return("single");

            case TypeCode.Double:
                return("double");

            case TypeCode.String:
                return("string");

            case TypeCode.Empty:
                return("null");

            case TypeCode.DBNull:
            case TypeCode.Decimal:
            case TypeCode.DateTime:
                return(type.FullName);
            }

            throw new NotImplementedException("No implementation for " + type);
        }
        public object Read(object value, ProtoReader source)

        {
            if (isRootType && value != null)
            {
                Callback(value, TypeModel.CallbackType.BeforeDeserialize, source.Context);
            }

            int fieldNumber, lastFieldNumber = 0, lastFieldIndex = 0;

            bool fieldHandled;



            //Helpers.DebugWriteLine(">> Reading fields for " + forType.FullName);

            while ((fieldNumber = source.ReadFieldHeader()) > 0)

            {
                fieldHandled = false;

                if (fieldNumber < lastFieldNumber)

                {
                    lastFieldNumber = lastFieldIndex = 0;
                }

                for (int i = lastFieldIndex; i < fieldNumbers.Length; i++)

                {
                    if (fieldNumbers[i] == fieldNumber)

                    {
                        IProtoSerializer ser = serializers[i];

                        //Helpers.DebugWriteLine(": " + ser.ToString());

                        Type serType = ser.ExpectedType;

                        if (value == null)

                        {
                            if (serType == forType)
                            {
                                value = CreateInstance(source, true);
                            }
                        }

                        else

                        {
                            if (serType != forType && ((IProtoTypeSerializer)ser).CanCreateInstance()

                                && serType

#if WINRT
                                .GetTypeInfo()
#endif

                                .IsSubclassOf(value.GetType()))

                            {
                                value = ProtoReader.Merge(source, value, ((IProtoTypeSerializer)ser).CreateInstance(source));
                            }
                        }



                        if (ser.ReturnsValue)
                        {
                            value = ser.Read(value, source);
                        }
                        else     // pop

                        {
                            ser.Read(value, source);
                        }



                        lastFieldIndex = i;

                        lastFieldNumber = fieldNumber;

                        fieldHandled = true;

                        break;
                    }
                }

                if (!fieldHandled)

                {
                    //Helpers.DebugWriteLine(": [" + fieldNumber + "] (unknown)");

                    if (value == null)
                    {
                        value = CreateInstance(source, true);
                    }

                    if (isExtensible)
                    {
                        source.AppendExtensionData((IExtensible)value);
                    }
                    else
                    {
                        source.SkipField();
                    }
                }
            }

            //Helpers.DebugWriteLine("<< Reading fields for " + forType.FullName);

            if (value == null)
            {
                value = CreateInstance(source, true);
            }

            if (isRootType)
            {
                Callback(value, TypeModel.CallbackType.AfterDeserialize, source.Context);
            }

            return(value);
        }
        void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)

        {
            Type expected = ExpectedType;

            Helpers.DebugAssert(valueFrom != null);



            using (Compiler.Local loc = ctx.GetLocalWithValue(expected, valueFrom))

                using (Compiler.Local fieldNumber = new Compiler.Local(ctx, ctx.MapType(typeof(int))))

                {
                    // pre-callbacks

                    if (HasCallbacks(TypeModel.CallbackType.BeforeDeserialize))

                    {
                        if (ExpectedType.IsValueType)

                        {
                            EmitCallbackIfNeeded(ctx, loc, TypeModel.CallbackType.BeforeDeserialize);
                        }

                        else

                        { // could be null
                            Compiler.CodeLabel callbacksDone = ctx.DefineLabel();

                            ctx.LoadValue(loc);

                            ctx.BranchIfFalse(callbacksDone, false);

                            EmitCallbackIfNeeded(ctx, loc, TypeModel.CallbackType.BeforeDeserialize);

                            ctx.MarkLabel(callbacksDone);
                        }
                    }



                    Compiler.CodeLabel @continue = ctx.DefineLabel(), processField = ctx.DefineLabel();

                    ctx.Branch(@continue, false);



                    ctx.MarkLabel(processField);

                    foreach (BasicList.Group group in BasicList.GetContiguousGroups(fieldNumbers, serializers))

                    {
                        Compiler.CodeLabel tryNextField = ctx.DefineLabel();

                        int groupItemCount = group.Items.Count;

                        if (groupItemCount == 1)

                        {
                            // discreet group; use an equality test

                            ctx.LoadValue(fieldNumber);

                            ctx.LoadValue(group.First);

                            Compiler.CodeLabel processThisField = ctx.DefineLabel();

                            ctx.BranchIfEqual(processThisField, true);

                            ctx.Branch(tryNextField, false);

                            WriteFieldHandler(ctx, expected, loc, processThisField, @continue, (IProtoSerializer)group.Items[0]);
                        }

                        else

                        { // implement as a jump-table-based switch
                            ctx.LoadValue(fieldNumber);

                            ctx.LoadValue(group.First);

                            ctx.Subtract(); // jump-tables are zero-based

                            Compiler.CodeLabel[] jmp = new Compiler.CodeLabel[groupItemCount];

                            for (int i = 0; i < groupItemCount; i++)
                            {
                                jmp[i] = ctx.DefineLabel();
                            }

                            ctx.Switch(jmp);

                            // write the default...

                            ctx.Branch(tryNextField, false);

                            for (int i = 0; i < groupItemCount; i++)

                            {
                                WriteFieldHandler(ctx, expected, loc, jmp[i], @continue, (IProtoSerializer)group.Items[i]);
                            }
                        }

                        ctx.MarkLabel(tryNextField);
                    }



                    EmitCreateIfNull(ctx, loc);

                    ctx.LoadReaderWriter();

                    if (isExtensible)

                    {
                        ctx.LoadValue(loc);

                        ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("AppendExtensionData"));
                    }

                    else

                    {
                        ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("SkipField"));
                    }



                    ctx.MarkLabel(@continue);

                    ctx.EmitBasicRead("ReadFieldHeader", ctx.MapType(typeof(int)));

                    ctx.CopyValue();

                    ctx.StoreValue(fieldNumber);

                    ctx.LoadValue(0);

                    ctx.BranchIfGreater(processField, false);



                    EmitCreateIfNull(ctx, loc);

                    // post-callbacks

                    EmitCallbackIfNeeded(ctx, loc, TypeModel.CallbackType.AfterDeserialize);



                    if (valueFrom != null && !loc.IsSame(valueFrom))

                    {
                        ctx.LoadValue(loc);

                        ctx.Cast(valueFrom.Type);

                        ctx.StoreValue(valueFrom);
                    }
                }
        }
Example #49
0
        internal static bool IdentifyImmutable(TypeModel model, Type declaredType, out MethodInfo builderFactory, out MethodInfo add, out MethodInfo addRange, out MethodInfo finish)
        {
            builderFactory = add = addRange = finish = null;
            if (model == null || declaredType == null)
            {
                return(false);
            }
#if WINRT
            TypeInfo declaredTypeInfo = declaredType.GetTypeInfo();
#else
            Type declaredTypeInfo = declaredType;
#endif

            // try to detect immutable collections; firstly, they are all generic, and all implement IReadOnlyCollection<T> for some T
            if (!declaredTypeInfo.IsGenericType)
            {
                return(false);
            }

#if WINRT
            Type[] typeArgs = declaredTypeInfo.GenericTypeArguments, effectiveType;
#else
            Type[] typeArgs = declaredTypeInfo.GetGenericArguments(), effectiveType;
#endif
            switch (typeArgs.Length)
            {
            case 1:
                effectiveType = typeArgs;
                break;     // fine

            case 2:
                Type kvp = model.MapType(typeof(System.Collections.Generic.KeyValuePair <,>));
                if (kvp == null)
                {
                    return(false);
                }
                kvp           = kvp.MakeGenericType(typeArgs);
                effectiveType = new Type[] { kvp };
                break;

            default:
                return(false);    // no clue!
            }

            if (ResolveIReadOnlyCollection(declaredType, null) == null)
            {
                return(false);                                                        // no IReadOnlyCollection<T> found
            }
            // and we want to use the builder API, so for generic Foo<T> or IFoo<T> we want to use Foo.CreateBuilder<T>
            string name = declaredType.Name;
            int    i    = name.IndexOf('`');
            if (i <= 0)
            {
                return(false);
            }
            name = declaredTypeInfo.IsInterface ? name.Substring(1, i - 1) : name.Substring(0, i);

            Type outerType = model.GetType(declaredType.Namespace + "." + name, declaredTypeInfo.Assembly);
            // I hate special-cases...
            if (outerType == null && name == "ImmutableSet")
            {
                outerType = model.GetType(declaredType.Namespace + ".ImmutableHashSet", declaredTypeInfo.Assembly);
            }
            if (outerType == null)
            {
                return(false);
            }

#if WINRT
            foreach (MethodInfo method in outerType.GetTypeInfo().DeclaredMethods)
#else
            foreach (MethodInfo method in outerType.GetMethods())
#endif
            {
                if (!method.IsStatic || method.Name != "CreateBuilder" || !method.IsGenericMethodDefinition || method.GetParameters().Length != 0 ||
                    method.GetGenericArguments().Length != typeArgs.Length)
                {
                    continue;
                }

                builderFactory = method.MakeGenericMethod(typeArgs);
                break;
            }
            Type voidType = model.MapType(typeof(void));
            if (builderFactory == null || builderFactory.ReturnType == null || builderFactory.ReturnType == voidType)
            {
                return(false);
            }


            add = Helpers.GetInstanceMethod(builderFactory.ReturnType, "Add", effectiveType);
            if (add == null)
            {
                return(false);
            }

            finish = Helpers.GetInstanceMethod(builderFactory.ReturnType, "ToImmutable", Helpers.EmptyTypes);
            if (finish == null || finish.ReturnType == null || finish.ReturnType == voidType)
            {
                return(false);
            }

            if (!(finish.ReturnType == declaredType || Helpers.IsAssignableFrom(declaredType, finish.ReturnType)))
            {
                return(false);
            }

            addRange = Helpers.GetInstanceMethod(builderFactory.ReturnType, "AddRange", new Type[] { declaredType });
            if (addRange == null)
            {
                Type enumerable = model.MapType(typeof(System.Collections.Generic.IEnumerable <>), false);
                if (enumerable != null)
                {
                    addRange = Helpers.GetInstanceMethod(builderFactory.ReturnType, "AddRange", new Type[] { enumerable.MakeGenericType(effectiveType) });
                }
            }

            return(true);
        }
        void IProtoTypeSerializer.EmitCallback(Compiler.CompilerContext ctx, Compiler.Local valueFrom, TypeModel.CallbackType callbackType)

        {
            bool actuallyHasInheritance = false;

            if (CanHaveInheritance)

            {
                for (int i = 0; i < serializers.Length; i++)

                {
                    IProtoSerializer ser = serializers[i];

                    if (ser.ExpectedType != forType && ((IProtoTypeSerializer)ser).HasCallbacks(callbackType))

                    {
                        actuallyHasInheritance = true;
                    }
                }
            }



            Helpers.DebugAssert(((IProtoTypeSerializer)this).HasCallbacks(callbackType), "Shouldn't be calling this if there is nothing to do");

            MethodInfo method = callbacks == null ? null : callbacks[callbackType];

            if (method == null && !actuallyHasInheritance)

            {
                return;
            }

            ctx.LoadAddress(valueFrom, ExpectedType);

            EmitInvokeCallback(ctx, method, actuallyHasInheritance, null, forType);



            if (actuallyHasInheritance)

            {
                Compiler.CodeLabel @break = ctx.DefineLabel();

                for (int i = 0; i < serializers.Length; i++)

                {
                    IProtoSerializer ser = serializers[i];

                    IProtoTypeSerializer typeser;

                    Type serType = ser.ExpectedType;

                    if (serType != forType &&

                        (typeser = (IProtoTypeSerializer)ser).HasCallbacks(callbackType))

                    {
                        Compiler.CodeLabel ifMatch = ctx.DefineLabel(), nextTest = ctx.DefineLabel();

                        ctx.CopyValue();

                        ctx.TryCast(serType);

                        ctx.CopyValue();

                        ctx.BranchIfTrue(ifMatch, true);

                        ctx.DiscardValue();

                        ctx.Branch(nextTest, false);

                        ctx.MarkLabel(ifMatch);

                        typeser.EmitCallback(ctx, null, callbackType);

                        ctx.Branch(@break, false);

                        ctx.MarkLabel(nextTest);
                    }
                }

                ctx.MarkLabel(@break);

                ctx.DiscardValue();
            }
        }
Example #51
0
        protected override void EmitWrite(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom)
        {
            using (Compiler.Local list = ctx.GetLocalWithValue(ExpectedType, valueFrom))
            {
                MethodInfo moveNext, current, getEnumerator = GetEnumeratorInfo(ctx.Model, out moveNext, out current);
                Helpers.DebugAssert(moveNext != null);
                Helpers.DebugAssert(current != null);
                Helpers.DebugAssert(getEnumerator != null);
                Type enumeratorType = getEnumerator.ReturnType;
                bool writePacked    = WritePacked;
                using (Compiler.Local iter = new Compiler.Local(ctx, enumeratorType))
                    using (Compiler.Local token = writePacked ? new Compiler.Local(ctx, ctx.MapType(typeof(SubItemToken))) : null)
                    {
                        if (writePacked)
                        {
                            ctx.LoadValue(fieldNumber);
                            ctx.LoadValue((int)WireType.String);
                            ctx.LoadReaderWriter();
                            ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("WriteFieldHeader"));

                            ctx.LoadValue(list);
                            ctx.LoadReaderWriter();
                            ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("StartSubItem"));
                            ctx.StoreValue(token);

                            ctx.LoadValue(fieldNumber);
                            ctx.LoadReaderWriter();
                            ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("SetPackedField"));
                        }

                        ctx.LoadAddress(list, ExpectedType);
                        ctx.EmitCall(getEnumerator);
                        ctx.StoreValue(iter);
                        using (ctx.Using(iter))
                        {
                            Compiler.CodeLabel body = ctx.DefineLabel(), next = ctx.DefineLabel();
                            ctx.Branch(next, false);

                            ctx.MarkLabel(body);

                            ctx.LoadAddress(iter, enumeratorType);
                            ctx.EmitCall(current);
                            Type itemType = Tail.ExpectedType;
                            if (itemType != ctx.MapType(typeof(object)) && current.ReturnType == ctx.MapType(typeof(object)))
                            {
                                ctx.CastFromObject(itemType);
                            }
                            Tail.EmitWrite(ctx, null);

                            ctx.MarkLabel(@next);
                            ctx.LoadAddress(iter, enumeratorType);
                            ctx.EmitCall(moveNext);
                            ctx.BranchIfTrue(body, false);
                        }

                        if (writePacked)
                        {
                            ctx.LoadValue(token);
                            ctx.LoadReaderWriter();
                            ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("EndSubItem"));
                        }
                    }
            }
        }
Example #52
0
        protected override void EmitRead(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom)
        {
            Type listType;

#if NO_GENERICS
            listType = typeof(BasicList);
#else
            listType = ctx.MapType(typeof(System.Collections.Generic.List <>)).MakeGenericType(itemType);
#endif
            Type expected = ExpectedType;
            using (Compiler.Local oldArr = AppendToCollection ? ctx.GetLocalWithValue(expected, valueFrom) : null)
                using (Compiler.Local newArr = new Compiler.Local(ctx, expected))
                    using (Compiler.Local list = new Compiler.Local(ctx, listType))
                    {
                        ctx.EmitCtor(listType);
                        ctx.StoreValue(list);
                        ListDecorator.EmitReadList(ctx, list, Tail, listType.GetMethod("Add"), packedWireType, false);

                        // leave this "using" here, as it can share the "FieldNumber" local with EmitReadList
                        using (Compiler.Local oldLen = AppendToCollection ? new ProtoBuf.Compiler.Local(ctx, ctx.MapType(typeof(int))) : null) {
                            Type[] copyToArrayInt32Args = new Type[] { ctx.MapType(typeof(Array)), ctx.MapType(typeof(int)) };

                            if (AppendToCollection)
                            {
                                ctx.LoadLength(oldArr, true);
                                ctx.CopyValue();
                                ctx.StoreValue(oldLen);

                                ctx.LoadAddress(list, listType);
                                ctx.LoadValue(listType.GetProperty("Count"));
                                ctx.Add();
                                ctx.CreateArray(itemType, null); // length is on the stack
                                ctx.StoreValue(newArr);

                                ctx.LoadValue(oldLen);
                                Compiler.CodeLabel nothingToCopy = ctx.DefineLabel();
                                ctx.BranchIfFalse(nothingToCopy, true);
                                ctx.LoadValue(oldArr);
                                ctx.LoadValue(newArr);
                                ctx.LoadValue(0); // index in target

                                ctx.EmitCall(expected.GetMethod("CopyTo", copyToArrayInt32Args));
                                ctx.MarkLabel(nothingToCopy);

                                ctx.LoadValue(list);
                                ctx.LoadValue(newArr);
                                ctx.LoadValue(oldLen);
                            }
                            else
                            {
                                ctx.LoadAddress(list, listType);
                                ctx.LoadValue(listType.GetProperty("Count"));
                                ctx.CreateArray(itemType, null);
                                ctx.StoreValue(newArr);

                                ctx.LoadAddress(list, listType);
                                ctx.LoadValue(newArr);
                                ctx.LoadValue(0);
                            }

                            copyToArrayInt32Args[0] = expected; // // prefer: CopyTo(T[], int)
                            MethodInfo copyTo = listType.GetMethod("CopyTo", copyToArrayInt32Args);
                            if (copyTo == null)
                            { // fallback: CopyTo(Array, int)
                                copyToArrayInt32Args[1] = ctx.MapType(typeof(Array));
                                copyTo = listType.GetMethod("CopyTo", copyToArrayInt32Args);
                            }
                            ctx.EmitCall(copyTo);
                        }
                        ctx.LoadValue(newArr);
                    }
        }
Example #53
0
        private static void EmitReadAndAddItem(Compiler.CompilerContext ctx, Compiler.Local list, IProtoSerializer tail, MethodInfo add, bool castListForAdd)
        {
            ctx.LoadAddress(list, list.Type); // needs to be the reference in case the list is value-type (static-call)
            if (castListForAdd)
            {
                ctx.Cast(add.DeclaringType);
            }
            Type itemType         = tail.ExpectedType;
            bool tailReturnsValue = tail.ReturnsValue;

            if (tail.RequiresOldValue)
            {
                if (Helpers.IsValueType(itemType) || !tailReturnsValue)
                {
                    // going to need a variable
                    using (Compiler.Local item = new Compiler.Local(ctx, itemType))
                    {
                        if (Helpers.IsValueType(itemType))
                        {   // initialise the struct
                            ctx.LoadAddress(item, itemType);
                            ctx.EmitCtor(itemType);
                        }
                        else
                        {   // assign null
                            ctx.LoadNullRef();
                            ctx.StoreValue(item);
                        }
                        tail.EmitRead(ctx, item);
                        if (!tailReturnsValue)
                        {
                            ctx.LoadValue(item);
                        }
                    }
                }
                else
                {    // no variable; pass the null on the stack and take the value *off* the stack
                    ctx.LoadNullRef();
                    tail.EmitRead(ctx, null);
                }
            }
            else
            {
                if (tailReturnsValue)
                {   // out only (on the stack); just emit it
                    tail.EmitRead(ctx, null);
                }
                else
                {   // doesn't take anything in nor return anything! WTF?
                    throw new InvalidOperationException();
                }
            }
            // our "Add" is chosen either to take the correct type, or to take "object";
            // we may need to box the value

            Type addParamType = add.GetParameters()[0].ParameterType;

            if (addParamType != itemType)
            {
                if (addParamType == ctx.MapType(typeof(object)))
                {
                    ctx.CastToObject(itemType);
                }
#if !NO_GENERICS
                else if (Helpers.GetUnderlyingType(addParamType) == itemType)
                {                       // list is nullable
                    ConstructorInfo ctor = Helpers.GetConstructor(addParamType, new Type[] { itemType }, false);
                    ctx.EmitCtor(ctor); // the itemType on the stack is now a Nullable<ItemType>
                }
#endif
                else
                {
                    throw new InvalidOperationException("Conflicting item/add type");
                }
            }
            ctx.EmitCall(add);
            if (add.ReturnType != ctx.MapType(typeof(void)))
            {
                ctx.DiscardValue();
            }
        }
 void AppendCATypeName(StringBuilder sb, Type type, string typeName, bool securityCompatHack = false)
 {
     if (type.IsArray)
     {
         AppendCATypeName(sb, type.GetElementType(), null);
         sb.Append("[]");
     }
     else if (type == typeofSystemBoolean)
     {
         sb.Append("bool");
     }
     else if (type == typeofSystemSByte)
     {
         sb.Append("int8");
     }
     else if (type == typeofSystemByte)
     {
         sb.Append("uint8");
     }
     else if (type == typeofSystemChar)
     {
         sb.Append("char");
     }
     else if (type == typeofSystemInt16)
     {
         sb.Append("int16");
     }
     else if (type == typeofSystemUInt16)
     {
         sb.Append("uint16");
     }
     else if (type == typeofSystemInt32)
     {
         sb.Append("int32");
     }
     else if (type == typeofSystemUInt32)
     {
         sb.Append("uint32");
     }
     else if (type == typeofSystemInt64)
     {
         sb.Append("int64");
     }
     else if (type == typeofSystemUInt64)
     {
         sb.Append("uint64");
     }
     else if (type == typeofSystemSingle)
     {
         sb.Append("float32");
     }
     else if (type == typeofSystemDouble)
     {
         sb.Append("float64");
     }
     else if (type == typeofSystemString)
     {
         sb.Append("string");
     }
     else if (type == typeofSystemObject)
     {
         sb.Append("object");
     }
     else if (type.FullName == "System.Type" && type.Assembly.GetName().Name == "mscorlib")
     {
         sb.Append("type");
     }
     else
     {
         sb.Append("enum ");
         AppendTypeName(sb, type, typeName, false, securityCompatHack);
     }
 }
Example #55
0
        public ArrayDecorator(TypeModel model, IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, Type arrayType, bool overwriteList, bool supportNull)
            : base(tail)
        {
            Helpers.DebugAssert(arrayType != null, "arrayType should be non-null");
            Helpers.DebugAssert(arrayType.IsArray && arrayType.GetArrayRank() == 1, "should be single-dimension array; " + arrayType.FullName);
            this.itemType = arrayType.GetElementType();
#if NO_GENERICS
            Type underlyingItemType = itemType;
#else
            Type underlyingItemType = supportNull ? itemType : (Helpers.GetUnderlyingType(itemType) ?? itemType);
#endif

            Helpers.DebugAssert(underlyingItemType == Tail.ExpectedType ||
                                (Tail.ExpectedType.ToString() == typeof(object).ToString() && !Helpers.IsValueType(underlyingItemType)), "invalid tail");
            Helpers.DebugAssert(Tail.ExpectedType != model.MapType(typeof(byte)), "Should have used BlobSerializer");
            if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0)
            {
                throw new ArgumentOutOfRangeException("fieldNumber");
            }
            if (!ListDecorator.CanPack(packedWireType))
            {
                if (writePacked)
                {
                    throw new InvalidOperationException("Only simple data-types can use packed encoding");
                }
                packedWireType = WireType.None;
            }
            this.fieldNumber    = fieldNumber;
            this.packedWireType = packedWireType;
            if (writePacked)
            {
                options |= OPTIONS_WritePacked;
            }
            if (overwriteList)
            {
                options |= OPTIONS_OverwriteList;
            }
            if (supportNull)
            {
                options |= OPTIONS_SupportNull;
            }
            this.arrayType = arrayType;
        }
Example #56
0
        protected ListDecorator(TypeModel model, Type declaredType, Type concreteType, IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, bool returnList, bool overwriteList, bool supportNull)
            : base(tail)
        {
            if (returnList)
            {
                options |= OPTIONS_ReturnList;
            }
            if (overwriteList)
            {
                options |= OPTIONS_OverwriteList;
            }
            if (supportNull)
            {
                options |= OPTIONS_SupportNull;
            }
            if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0)
            {
                throw new ArgumentOutOfRangeException("fieldNumber");
            }
            if (!CanPack(packedWireType))
            {
                if (writePacked)
                {
                    throw new InvalidOperationException("Only simple data-types can use packed encoding");
                }
                packedWireType = WireType.None;
            }

            this.fieldNumber = fieldNumber;
            if (writePacked)
            {
                options |= OPTIONS_WritePacked;
            }
            this.packedWireType = packedWireType;
            if (declaredType == null)
            {
                throw new ArgumentNullException("declaredType");
            }
            if (declaredType.IsArray)
            {
                throw new ArgumentException("Cannot treat arrays as lists", "declaredType");
            }
            this.declaredType = declaredType;
            this.concreteType = concreteType;

            // look for a public list.Add(typedObject) method
            if (RequireAdd)
            {
                bool isList;
                add = TypeModel.ResolveListAdd(model, declaredType, tail.ExpectedType, out isList);
                if (isList)
                {
                    options |= OPTIONS_IsList;
                    string fullName = declaredType.FullName;
                    if (fullName != null && fullName.StartsWith("System.Data.Linq.EntitySet`1[["))
                    { // see http://stackoverflow.com/questions/6194639/entityset-is-there-a-sane-reason-that-ilist-add-doesnt-set-assigned
                        options |= OPTIONS_SuppressIList;
                    }
                }
                if (add == null)
                {
                    throw new InvalidOperationException("Unable to resolve a suitable Add method for " + declaredType.FullName);
                }
            }
        }
Example #57
0
 bool Compare(Type a, Type b)
 {
     return(a == b ||
            a.IsGenericType && b.IsGenericType &&
            a.GetGenericTypeDefinition() == b.GetGenericTypeDefinition());
 }
        static void EmitInvokeCallback(Compiler.CompilerContext ctx, MethodInfo method, bool copyValue, Type constructType, Type type)

        {
            if (method != null)

            {
                if (copyValue)
                {
                    ctx.CopyValue();           // assumes the target is on the stack, and that we want to *retain* it on the stack
                }
                ParameterInfo[] parameters = method.GetParameters();

                bool handled = true;



                for (int i = 0; i < parameters.Length; i++)

                {
                    Type parameterType = parameters[0].ParameterType;

                    if (parameterType == ctx.MapType(typeof(SerializationContext)))

                    {
                        ctx.LoadSerializationContext();
                    }

                    else if (parameterType == ctx.MapType(typeof(System.Type)))

                    {
                        Type tmp = constructType;

                        if (tmp == null)
                        {
                            tmp = type;              // no ?? in some C# profiles
                        }
                        ctx.LoadValue(tmp);
                    }

#if PLAT_BINARYFORMATTER
                    else if (parameterType == ctx.MapType(typeof(System.Runtime.Serialization.StreamingContext)))

                    {
                        ctx.LoadSerializationContext();

                        MethodInfo op = ctx.MapType(typeof(SerializationContext)).GetMethod("op_Implicit", new Type[] { ctx.MapType(typeof(SerializationContext)) });

                        if (op != null)

                        { // it isn't always! (framework versions, etc)
                            ctx.EmitCall(op);

                            handled = true;
                        }
                    }
#endif

                    else

                    {
                        handled = false;
                    }
                }

                if (handled)

                {
                    ctx.EmitCall(method);

                    if (constructType != null)

                    {
                        if (method.ReturnType == ctx.MapType(typeof(object)))

                        {
                            ctx.CastFromObject(type);
                        }
                    }
                }

                else

                {
                    throw Meta.CallbackSet.CreateInvalidCallbackSignature(method);
                }
            }
        }
Example #59
0
        public DecimalSerializer(ProtoBuf.Meta.TypeModel model)
        {
#if FEAT_IKVM
            expectedType = model.MapType(typeof(decimal));
#endif
        }
        void ReadFixedArg(StringBuilder sb, ByteReader br, Type type, bool arrayElement = false)
        {
            if (type.IsArray)
            {
                int length = br.ReadInt32();
                if (length == -1 && compat == CompatLevel.None)
                {
                    sb.Append("nullref");
                }
                else if (length == 0 && compat != CompatLevel.None)
                {
                    throw new IKVM.Reflection.BadImageFormatException();
                }
                else
                {
                    Type elementType = type.GetElementType();
                    AppendCATypeName(sb, elementType, null);
                    sb.AppendFormat("[{0}](", length);
                    for (int i = 0; i < length; i++)
                    {
                        if (i != 0)
                        {
                            sb.Append(' ');
                        }
                        if (elementType == typeofSystemObject)
                        {
                            string typeName;
                            ReadFixedArg(sb, br, ReadFieldOrPropType(sb, br, out typeName), false);
                        }
                        else
                        {
                            ReadFixedArg(sb, br, elementType, true);
                        }
                    }
                    sb.Append(')');
                }
            }
            else if (type.FullName == "System.Type" && type.Assembly.GetName().Name == "mscorlib")
            {
                if (!arrayElement)
                {
                    AppendCATypeName(sb, type, null);
                    sb.Append('(');
                }
                string typeName;
                var    type1 = ReadType(br, out typeName);
                if (type1 == null)
                {
                    if (typeName == null)
                    {
                        sb.Append("nullref");
                    }
                    else
                    {
                        sb.Append("class ").Append(QuoteIdentifier(typeName, true));
                    }
                }
                else
                {
                    AppendTypeName(sb, type1, typeName, compat != CompatLevel.None && IsNestedTypeWithNamespace(type1));
                }
                if (!arrayElement)
                {
                    sb.Append(')');
                }
            }
            else if (type.Assembly == mscorlib)
            {
                if (!arrayElement)
                {
                    AppendCATypeName(sb, type, null);
                    sb.Append('(');
                }
                if (type == typeofSystemBoolean)
                {
                    sb.Append(br.ReadByte() == 0 ? "false" : "true");
                }
                else if (type == typeofSystemByte)
                {
                    sb.Append(br.ReadByte());
                }
                else if (type == typeofSystemSByte)
                {
                    sb.Append(br.ReadSByte());
                }
                else if (type == typeofSystemChar)
                {
                    sb.AppendFormat("0x{0:X4}", (int)br.ReadChar());
                }
                else if (type == typeofSystemInt16)
                {
                    sb.Append(br.ReadInt16());
                }
                else if (type == typeofSystemUInt16)
                {
                    sb.Append(br.ReadUInt16());
                }
                else if (type == typeofSystemInt32)
                {
                    sb.Append(br.ReadInt32());
                }
                else if (type == typeofSystemUInt32)
                {
                    sb.Append(br.ReadInt32());
                }
                else if (type == typeofSystemInt64)
                {
                    sb.Append(br.ReadInt64());
                }
                else if (type == typeofSystemUInt64)
                {
                    sb.Append(br.ReadInt64());
                }
                else if (type == typeofSystemSingle)
                {
                    sb.Append(ToString(br.ReadSingle(), true));
                }
                else if (type == typeofSystemDouble)
                {
                    sb.Append(ToString(br.ReadDouble(), true));
                }
                else if (type == typeofSystemString)
                {
                    var str = br.ReadString();
                    if (str == null)
                    {
                        sb.Append("nullref");
                    }
                    else
                    {
                        if (compat != CompatLevel.None)
                        {
                            int pos = str.IndexOf((char)0);
                            if (pos != -1)
                            {
                                str = str.Substring(0, pos);
                            }
                        }
                        sb.Append(QuoteIdentifier(str, true));
                    }
                }
                else if (type == typeofSystemObject)
                {
                    string typeName;
                    ReadFixedArg(sb, br, ReadFieldOrPropType(sb, br, out typeName));
                }
                else
                {
                    throw new NotImplementedException(type.FullName);
                }
                if (!arrayElement)
                {
                    sb.Append(')');
                }
            }
            else if (type.__IsMissing || (compat != CompatLevel.None && typerefs.Contains(type)))
            {
                // ildasm actually tries to load the assembly, but we can't do that, so we cheat by having
                // a list of 'known' enum types
                if (type.Assembly.GetName().Name == "mscorlib")
                {
                    switch (type.FullName)
                    {
                    case "System.AttributeTargets":
                    case "System.Runtime.ConstrainedExecution.Consistency":
                    case "System.Runtime.ConstrainedExecution.Cer":
                    case "System.Security.Permissions.SecurityAction":
                    case "System.Security.Permissions.SecurityPermissionFlag":
                    case "System.Runtime.Versioning.ResourceScope":
                    case "System.Runtime.InteropServices.CallingConvention":
                    case "System.Runtime.InteropServices.CharSet":
                        ReadFixedArg(sb, br, typeofSystemInt32);
                        return;

                    case "System.Security.SecurityRuleSet":
                        if (compat != CompatLevel.V20)
                        {
                            ReadFixedArg(sb, br, typeofSystemByte);
                            return;
                        }
                        break;

                    case "System.Diagnostics.Tracing.EventLevel":
                    case "System.Diagnostics.Tracing.EventTask":
                    case "System.Diagnostics.Tracing.EventOpcode":
                        if (compat != CompatLevel.V20 && compat != CompatLevel.V40)
                        {
                            ReadFixedArg(sb, br, typeofSystemInt32);
                            return;
                        }
                        break;

                    case "System.Type":
                        sb.Append("type(");
                        string typeName;
                        AppendTypeName(sb, ReadType(br, out typeName), typeName);
                        sb.Append(")");
                        return;
                    }
                }
                switch (br.Length)
                {
                case 1:
                    if (compat != CompatLevel.None)
                    {
                        // ildasm uses bool (???) as the underlying type in this case
                        sb.AppendFormat("bool({0})", br.ReadByte() == 0 ? "false" : "true");
                    }
                    else
                    {
                        // just guess that the enum has int8 as the underlying type
                        sb.AppendFormat("int8({0})", br.ReadSByte());
                    }
                    break;

                case 2:
                    // just guess that the enum has int16 as the underlying type
                    sb.AppendFormat("int16({0})", br.ReadInt16());
                    break;

                case 4:
                    // just guess that the enum has int32 as the underlying type
                    sb.AppendFormat("int32({0})", br.ReadInt32());
                    break;

                case 8:
                    // just guess that the enum has int64 as the underlying type
                    sb.AppendFormat("int64({0})", br.ReadInt64());
                    break;

                default:
                    throw new IKVM.Reflection.BadImageFormatException();
                }
            }
            else if (type.IsEnum)
            {
                ReadFixedArg(sb, br, type.GetEnumUnderlyingType(), arrayElement);
            }
            else
            {
                throw new NotImplementedException(type.FullName);
            }
        }