Beispiel #1
0
 internal CILFieldImpl(
     CILReflectionContextImpl ctx,
     Int32 anID,
     CILType declaringType,
     String name,
     CILTypeBase fieldType,
     FieldAttributes attrs
     )
     : this(
         ctx,
         anID,
         new LazyWithLock <ListProxy <CILCustomAttribute> >(() => ctx.CollectionsFactory.NewListProxy <CILCustomAttribute>()),
         new SettableValueForEnums <FieldAttributes>(attrs),
         new SettableValueForClasses <String>(name),
         () => declaringType,
         () => fieldType,
         new SettableLazy <Object>(() => null),
         new SettableValueForClasses <Byte[]>(null),
         new LazyWithLock <ListProxy <CILCustomModifier> >(() => ctx.CollectionsFactory.NewListProxy <CILCustomModifier>()),
         new SettableLazy <Int32>(() => NO_OFFSET),
         new SettableLazy <MarshalingInfo>(() => null),
         true
         )
 {
 }
Beispiel #2
0
        internal void BeginCatchBlock(CILTypeBase exceptionType)
        {
            var info = this._currentExceptionBlocks.Peek();

            info._exceptionType = exceptionType;
            info.HandlerBegun(ExceptionBlockType.Exception, this._opCodes.Count);
        }
Beispiel #3
0
 internal static void CheckTypeForMethodSig(CILModule thisModule, ref CILTypeBase type)
 {
     if (TypeKind.MethodSignature == type.TypeKind && !Object.Equals(thisModule, type.Module))
     {
         type = ((CILMethodSignature)type).CopyToOtherModule(thisModule);
     }
 }
Beispiel #4
0
 internal LocalBuilderImpl(Int32 idx, CILTypeBase type, Boolean pinned)
 {
     ArgumentValidator.ValidateNotNull("Local type", type);
     this._idx       = idx;
     this._localType = type;
     this._pinned    = pinned;
 }
Beispiel #5
0
        private static Boolean MatchParameterTypes(CILTypeBase type1, CILTypeBase type2)
        {
            // TODO we here assume that portable assemblies won't contain method signature types
            var retVal = type1 == null && type2 == null;

            if (!retVal && type1 != null && type2 != null && type1.TypeKind == type2.TypeKind)
            {
                if (type1.TypeKind == TypeKind.Type)
                {
                    var t1 = (CILType)type1;
                    var t2 = (CILType)type2;

                    retVal = MatchParameterTypesTextually(t1, t2) &&
                             MatchParameterTypes(t1.ElementType, t2.ElementType) &&
                             t1.ElementKind == t2.ElementKind &&
                             Object.Equals(t1.ArrayInformation, t2.ArrayInformation);
                }
                else if (type1.TypeKind == TypeKind.TypeParameter)
                {
                    retVal = ((CILTypeParameter)type1).GenericParameterPosition == ((CILTypeParameter)type2).GenericParameterPosition &&
                             MatchParameterTypes(((CILTypeParameter)type1).DeclaringType, ((CILTypeParameter)type2).DeclaringType);
                }
            }

            return(retVal);
        }
Beispiel #6
0
        protected virtual void CreateEmittingActionsForEvent(
            EventModel eventModel,
            CILTypeBase eventType,
            out CILTypeBase fieldType,
            out Action <CILField, MethodIL> addAction,
            out Action <CILField, MethodIL> removeAction,
            out Action <EventModel, CompositeTypeGenerationInfo, CILField, CILTypeBase, CompositeMethodGenerationInfo, CILMethod> invokeAction,
            out Action <CILField, MethodIL> checkAction
            )
        {
            //var storage = eventModel.GetEventStorageKind();

            //if ( EventStorage.STRONG_REFS.Equals( storage ) )
            //{
            fieldType    = eventType;
            addAction    = (eventField, il) => this.EmitEventModificationMethodForStronglyReferencedEvents(eventField, il, DELEGATE_COMBINE_METHOD);
            removeAction = (eventField, il) => this.EmitEventModificationMethodForStronglyReferencedEvents(eventField, il, DELEGATE_REMOVE_METHOD);
            invokeAction = this.EmitEventInvocationMethodForStronglyReferencedEvents;
            checkAction  = this.EmitEventCheckMethodForStronglyReferencedEvents;
            //}
            //else
            //{
            //   fieldType = WEAK_EVENT_WRAPPER_TYPE;
            //   addAction = this.EmitEventAdditionMethodForWeaklyReferencedEvents;
            //   removeAction = this.EmitEventRemovingMethodForWeaklyReferencedEvents;
            //   invokeAction = this.EmitEventInvocationMethodForWeaklyReferencedEvents;
            //   checkAction = this.EmitEventCheckMethodForWeaklyReferencedEvents;
            //}
        }
Beispiel #7
0
        public LocalBuilder DeclareLocal(CILTypeBase type, Boolean pinned = false)
        {
            LogicalUtils.CheckTypeForMethodSig(this._module, ref type);
            var result = new LocalBuilderImpl(this._locals.Count, type, pinned);

            this._locals.Add(result);
            return(result);
        }
Beispiel #8
0
 internal void Emit(OpCode code, CILTypeBase type, Boolean useGDefIfPossible)
 {
     ArgumentValidator.ValidateNotNull("Type", type);
     this.BeforeEmittingOpCode();
     this.EmitOpCode(code);
     this.UpdateStackSize(code, null, null);
     this.AddInt32(this._metaData.GetTokenFor(this._assemblyMapper.TryMapTypeBase(type), useGDefIfPossible && code.OperandType == OperandType.InlineTok));
 }
Beispiel #9
0
        private static void CreateTypeStringCore(CILTypeBase type, CILModule moduleBeingEmitted, StringBuilder builder, Boolean appendGArgs)
        {
            var eKind = type.GetElementKind();

            if (eKind.HasValue)
            {
                CreateTypeStringCore(type.GetElementType(), moduleBeingEmitted, builder, appendGArgs);
                CreateElementKindString(eKind.Value, ((CILType)type).ArrayInformation, builder);
            }
            else if (appendGArgs && type.IsGenericType() && !type.ContainsGenericParameters())
            {
                var typee = (CILType)type;
                CreateTypeStringCore(typee.GenericDefinition, moduleBeingEmitted, builder, false);
                builder.Append('[');
                var gArgs = typee.GenericArguments;
                for (var i = 0; i < gArgs.Count; ++i)
                {
                    CreateTypeString(gArgs[i], moduleBeingEmitted, builder, true, true);
                    if (i < gArgs.Count - 1)
                    {
                        builder.Append(',');
                    }
                }
                builder.Append(']');
            }
            else
            {
                switch (type.TypeKind)
                {
                case TypeKind.Type:
                    var typee = (CILType)type;
                    var dt    = typee.DeclaringType;
                    if (dt == null)
                    {
                        var ns = typee.Namespace;
                        if (!String.IsNullOrEmpty(ns))
                        {
                            builder.Append(EscapeSomeString(ns)).Append(CILTypeImpl.NAMESPACE_SEPARATOR);
                        }
                    }
                    else
                    {
                        CreateTypeStringCore(dt, moduleBeingEmitted, builder, false);
                        builder.Append('+');
                    }
                    builder.Append(EscapeSomeString(typee.Name));
                    break;

                case TypeKind.MethodSignature:
                    builder.Append(type.ToString());
                    break;

                case TypeKind.TypeParameter:
                    builder.Append(((CILTypeParameter)type).Name);
                    break;
                }
            }
        }
Beispiel #10
0
        internal CILParameterSignatureImpl(CILReflectionContext ctx, CILMethodSignature method, Int32 position, CILTypeBase pType, ListProxy <CILCustomModifier> mods)
            : base(ctx)
        {
            ArgumentValidator.ValidateNotNull("Method", method);
            ArgumentValidator.ValidateNotNull("Parameter type", pType);

            this._mods     = (mods ?? this._ctx.CollectionsFactory.NewListProxy <CILCustomModifier>()).CQ;
            this._method   = method;
            this._position = position;
            this._pType    = pType;
        }
Beispiel #11
0
        public CILParameter AddParameter(String name, ParameterAttributes attrs, CILTypeBase paramType)
        {
            this.ThrowIfNotCapableOfChanging();
            CILParameter result;

            lock (this.parameters.Lock)
            {
                result = this.context.Cache.NewBlankParameter(this, this.parameters.Value.CQ.Count, name, attrs, paramType);
                this.parameters.Value.Add(result);
            }
            this.context.Cache.ForAllGenericInstancesOf <CILMethodBase, CILMethodBaseInternal>((CILMethodBase)this, method => method.ResetParameterList());
            return(result);
        }
        private static TMethod GetMethodBase <TMethod>(CILTypeBase propType, TMethod method, TypeGenerationInfo thisGenInfo)
            where TMethod : CILMethodBase
        {
            var declType = method.DeclaringType;

            return(TypeGenerationUtils.GetMethodForEmitting(t => TypeGenerationUtils.CreateTypeForEmittingCILType(TypeGenerationUtils.GenericDefinitionIfGArgsHaveGenericParams(declType).MakeGenericType(propType.GetGenericArgumentsArray()), thisGenInfo.GenericArguments, null), method));
            //var declType = method.DeclaringType;
            //return propType.ContainsGenericParameters() ?
            //   TypeGenerationUtils.GetMethodForEmitting( type => TypeGenerationUtils.CreateTypeForEmitting( declType.IsGenericType ?
            //      declType.GetGenericTypeDefinition().MakeGenericType( propType.GetGenericArguments() ) :
            //      declType, thisGenInfo.GenericArguments, null ), method ) :
            //   (TMethod) MethodBase.GetMethodFromHandle( method.MethodHandle, ( declType.IsGenericType ?
            //      declType.GetGenericTypeDefinition().MakeGenericType( propType.GetGenericArguments() ) :
            //      declType ).TypeHandle );
        }
        protected virtual void EmitPropertySetterMethod(
            CompositeCodeGenerationInfo codeGenerationInfo,
            PropertyModel propertyModel,
            CompositeTypeGenerationInfo publicCompositeGenInfo,
            CompositeTypeGenerationInfo thisGenerationInfo,
            CILField propertyField,
            CILTypeBase fieldType,
            CILTypeBase propertyType,
            CompositeMethodGenerationInfo methodGenInfo,
            Action <CILField, MethodIL> writeAction
            )
        {
            // Code for setting properties:
            // internal void Property<idx>Setter(<property type> value )
            // {
            //    CompositeInstance instance = this._instance;
            //    <if the property is immutable>
            //    if ( !this._instance.IsPrototype )
            //    {
            //       throw new InvalidOperationException( "Can not set immutable propery " + QualifiedName.FromTypeAndName( <declaring type>, <name> ) + " for a non-prototype composite instance." );
            //    }
            //    <end if>
            //    <write property field>
            // }
            var il = methodGenInfo.IL;

            il.EmitLoadThisField(thisGenerationInfo.CompositeField)
            .EmitStoreLocal(methodGenInfo.GetOrCreateLocal(LB_C_INSTANCE, codeGenerationInfo.CompositeInstanceFieldType.NewWrapper(this.ctx)));

            this.EmitThrowIfApplicationNotActive(methodGenInfo);

            this.EmitProcessParameters(codeGenerationInfo, propertyModel.SetterMethod, true, publicCompositeGenInfo, thisGenerationInfo, methodGenInfo);

            this.EmitThrowIfViolations(thisGenerationInfo, methodGenInfo, propertyModel.SetterMethod);

            this.EmitCheckPropertyImmutability(propertyModel, thisGenerationInfo, il);

            writeAction(propertyField, il);

            il
            .EmitPop()
            .EmitReturn();
        }
Beispiel #14
0
        private static void CreateTypeString(CILTypeBase type, CILModule moduleBeingEmitted, StringBuilder builder, Boolean appendGArgs, Boolean isGParam)
        {
            var needsAssembly = moduleBeingEmitted != null && !moduleBeingEmitted.Assembly.Equals(type.Module.Assembly);

            if (isGParam && needsAssembly)
            {
                builder.Append('[');
            }
            CreateTypeStringCore(type, moduleBeingEmitted, builder, appendGArgs);
            if (needsAssembly)
            {
                builder
                .Append(TYPE_ASSEMBLY_SEPARATOR)
                .Append(type.Module.Assembly.Name.ToString());  // Assembly name will be escaped.
                if (isGParam)
                {
                    builder.Append(']');
                }
            }
        }
        protected virtual void EmitPropertyGetterMethod(
            CompositeCodeGenerationInfo codeGenerationInfo,
            PropertyModel propertyModel,
            CompositeTypeGenerationInfo publicCompositeGenInfo,
            CompositeTypeGenerationInfo thisGenerationInfo,
            CILField propertyField,
            CILTypeBase propertyType,
            CompositeMethodGenerationInfo methodGenInfo,
            Action <CILField, MethodIL> readAction
            )
        {
            // Code for getting properties:
            // public <property type> Property<idx>Getter( )
            // {
            //    CompositeInstance instance = this._instance;
            //    <check application active>
            //    var result = <read property field>;
            //    <check constraints>
            //    return result;
            // }
            var il = methodGenInfo.IL;

            il.EmitLoadThisField(thisGenerationInfo.CompositeField)
            .EmitStoreLocal(methodGenInfo.GetOrCreateLocal(LB_C_INSTANCE, codeGenerationInfo.CompositeInstanceFieldType.NewWrapper(this.ctx)));
            this.EmitThrowIfApplicationNotActive(methodGenInfo);

            var resultB = methodGenInfo.GetOrCreateLocal(LB_RESULT, methodGenInfo.ReturnType);

            readAction(propertyField, il);
            il.EmitStoreLocal(resultB);

            this.EmitProcessParameters(codeGenerationInfo, propertyModel.GetterMethod, false, publicCompositeGenInfo, thisGenerationInfo, methodGenInfo);
            this.EmitProcessResult(codeGenerationInfo, propertyModel.GetterMethod, publicCompositeGenInfo, thisGenerationInfo, methodGenInfo);

            this.EmitThrowIfViolations(thisGenerationInfo, methodGenInfo, propertyModel.GetterMethod);

            il.EmitLoadLocal(resultB)
            .EmitReturn();
        }
        protected virtual void EmitPropertyExchangeMethod(
            PropertyModel propertyModel,
            CompositeTypeGenerationInfo thisGenerationInfo,
            CILField propertyField,
            CILTypeBase fieldType,
            CILTypeBase propertyType,
            CILMethod propertySetter,
            CompositeMethodGenerationInfo methodGenInfo,
            Action <CILField, MethodIL> exchangeAction
            )
        {
            var il = methodGenInfo.IL;

            this.EmitThrowIfApplicationNotActiveWithoutLocalVariable(thisGenerationInfo, il);

            this.EmitCheckPropertyImmutability(propertyModel, thisGenerationInfo, il);

            exchangeAction(propertyField, il);
            il
            .EmitCastToType(fieldType, propertyType)
            .EmitReturn();
        }
Beispiel #17
0
 /// <summary>
 /// Creates new instance of <see cref="OpCodeInfoWithTypeToken"/> with specified values.
 /// </summary>
 /// <param name="opCode">The <see cref="OpCode"/> to emit.</param>
 /// <param name="type">The <see cref="CILTypeBase"/> to have as operand.</param>
 /// <param name="useGDefIfPossible">
 /// If this is <c>true</c>, and <paramref name="type"/> is generic type definition, and the declaring type of method containing this IL is <paramref name="type"/>, then a TypeDef-token will be emitted instead of TypeSpec.
 /// The default behaviour in such scenario is to emit TypeSpec token.
 /// </param>
 /// <exception cref="ArgumentNullException">If <paramref name="type"/> is <c>null</c>.</exception>
 public OpCodeInfoWithTypeToken(OpCode opCode, CILTypeBase type, Boolean useGDefIfPossible = false)
     : base(opCode, useGDefIfPossible)
 {
     ArgumentValidator.ValidateNotNull("Type", type);
     this._type = type;
 }
Beispiel #18
0
 internal CILEventImpl(CILReflectionContextImpl ctx, Int32 anID, CILType declaringType, String aName, EventAttributes anEventAttributes, CILTypeBase anEventType)
     : this(
         ctx,
         anID,
         new LazyWithLock <ListProxy <CILCustomAttribute> >(() => ctx.CollectionsFactory.NewListProxy <CILCustomAttribute>()),
         new SettableValueForClasses <String>(aName),
         new SettableValueForEnums <EventAttributes>(anEventAttributes),
         () => anEventType,
         () => null,
         () => null,
         () => null,
         () => ctx.CollectionsFactory.NewListProxy <CILMethod>(),
         () => declaringType,
         true)
 {
 }
Beispiel #19
0
        protected virtual void EmitEventInvocationMethodCore(
            EventModel eventModel,
            CompositeTypeGenerationInfo thisGenerationInfo,
            CILField eventField,
            CILTypeBase fieldType,
            CompositeMethodGenerationInfo invokeMethod,
            CILMethod eventMethodToInvoke,
            Action <LocalBuilder, EventInvocation, Type> actualEventInvoking
            )
        {
            var eventInfo = eventModel.NativeInfo;
            var il        = invokeMethod.IL;

            var eventLB             = il.DeclareLocal(fieldType);
            var afterNullCheckLabel = il.DefineLabel();

            il
            .EmitLoadThisField(eventField)
            .EmitStoreLocal(eventLB)
            .EmitLoadLocal(eventLB)
            .EmitBranch(BranchType.IF_FALSE, afterNullCheckLabel);

            EventInvocation invocationStyle;
            Type            exceptionType;

            this.GetEventInvocationStyle(eventModel, out invocationStyle, out exceptionType);

            actualEventInvoking(eventLB, invocationStyle, exceptionType);

            // Throw exception if needed
            if (EventInvocation.INVOKE_ALL.Equals(invocationStyle))
            {
                // TODO TODO TODO
                this.EmitThrowIfExceptionListHasAny(invokeMethod, exceptionType.GetConstructor(EXCEPTION_ENUMERABLE_ARRAY).NewWrapper(this.ctx));
            }

            if (!VOID_TYPE.Equals(eventMethodToInvoke.GetReturnType()))
            {
                //LocalBuilder amountOfDeadB;
                //if ( invokeMethod.TryGetLocal( LB_AMOUNT_OF_DEAD_EVENT_INFOS, out amountOfDeadB ) )
                //{
                //   il
                //      .EmitLoadLocal( amountOfDeadB )
                //      .EmitBranch( BranchType.IF_FALSE, afterNullCheckLabel );
                //}
                LocalBuilder resultB;
                if (invokeMethod.TryGetLocal(LB_RESULT, out resultB))
                {
                    il.EmitLoadLocal(resultB);
                }
                var returnLabel = il.DefineLabel();
                il
                .EmitBranch(BranchType.ALWAYS, returnLabel)
                .MarkLabel(afterNullCheckLabel)
                .EmitLoadString("The event " + eventInfo.Name + " in ")
                .EmitReflectionObjectOf(TypeGenerationUtils.CreateTypeForEmitting(eventInfo.DeclaringType.NewWrapper(this.ctx), thisGenerationInfo.GenericArguments, null))
                .EmitCall(TO_STRING_METHOD)
                .EmitLoadString(" is not set.")
                .EmitCall(STRING_CONCAT_METHOD_3)
                .EmitThrowNewException(INVALID_OPERATION_EXCEPTION_CTOR_WITH_STRING)
                .MarkLabel(returnLabel);
            }
            else
            {
                il.MarkLabel(afterNullCheckLabel);
            }

            il.EmitReturn();
        }
Beispiel #20
0
 internal CILParameterImpl(CILReflectionContextImpl ctx, Int32 anID, CILMethodBase ownerMethod, Int32 position, String name, ParameterAttributes attrs, CILTypeBase paramType)
     : this(
         ctx,
         anID,
         new LazyWithLock <ListProxy <CILCustomAttribute> >(() => ctx.CollectionsFactory.NewListProxy <CILCustomAttribute>()),
         new SettableValueForEnums <ParameterAttributes>(attrs),
         position,
         new SettableValueForClasses <String>(name),
         () => ownerMethod,
         () => paramType,
         new SettableLazy <Object>(() => null),
         new LazyWithLock <ListProxy <CILCustomModifier> >(() => ctx.CollectionsFactory.NewListProxy <CILCustomModifier>()),
         new SettableLazy <MarshalingInfo>(() => null),
         true
         )
 {
 }
Beispiel #21
0
 public CILTypeBase MapTypeBase(CILTypeBase type)
 {
     return(TypeKind.Type == type.TypeKind ? (CILTypeBase)this.MapType((CILType)type) : this.MapTypeParameter((CILTypeParameter)type));
 }
        protected virtual void GetReadAndWriteMethods(
            CILTypeBase propertyType,
            out Action <CILField, MethodIL> read,
            out Action <CILField, MethodIL> read32,
            out Action <CILField, MethodIL> write,
            out Action <CILField, MethodIL> compareExchange,
            out CILTypeBase fieldType
            )
        {
            fieldType = propertyType;
            //         Boolean isBooleanProperty = BOOLEAN_TYPE.Equals( propertyType );
            // We must ask whether type is value type before asking whether it is enum, because type builder proxies throw if asked directly if it is enum.
            Action <CILTypeBase, CILTypeBase, MethodIL> fieldToPropertyCast = null;
            Action <CILTypeBase, CILTypeBase, MethodIL> propertyToFieldCast = null;
            CILMethod iExchangeMethod;
            CILMethod iCompareExchangeMethod;
            var       tc = propertyType.GetTypeCode(CILTypeCode.Empty);

            switch (tc)
            {
            case CILTypeCode.Object:
            case CILTypeCode.SystemObject:
            case CILTypeCode.Type:
            case CILTypeCode.String:
            case CILTypeCode.DateTime:
            case CILTypeCode.Decimal:
            case CILTypeCode.Empty:
            case CILTypeCode.IntPtr:
            case CILTypeCode.UIntPtr:
                var isObject = tc == CILTypeCode.SystemObject;
                var isIntPtr = tc == CILTypeCode.IntPtr;
                // TODO if generic parameter has same constraint as Interlocked.Exchange<T>, we can use the Interlocked.Exchange<T> directly.
                if (propertyType.IsGenericParameter() ||
                    (propertyType.IsValueType() && /*&& !propertyType.IsInterface() && !isObject*/
                     (this.isSilverLight || !isIntPtr)
                    ))
                {
                    // TODO if value type => maybe use placeholder class? (Like System.Lazy<T> does)
                    fieldType = OBJECT_TYPE;
                }
                // SL doesn't have IntPtr or Object Interlocked.Exchange methods
                iExchangeMethod = (this.isSilverLight || (!isIntPtr && !isObject)) ? INTERLOCKED_EXCHANGE_METHOD_GDEF.MakeGenericMethod(fieldType) :
                                  (isIntPtr ? INTERLOCKED_EXCHANGE_INT_PTR_METHOD : INTERLOCKED_EXCHANGE_OBJECT_METHOD);
                // SL doesn't have IntPtr Interlocked.CompareExchange method (but oddly enough has the Object variation)
                iCompareExchangeMethod = isObject ? INTERLOCKED_COMPARE_EXCHANGE_OBJECT_METHOD :
                                         ((this.isSilverLight || !isIntPtr) ? INTERLOCKED_COMPARE_EXCHANGE_METHOD_GDEF.MakeGenericMethod(fieldType) : INTERLOCKED_COMPARE_EXCHANGE_INT_PTR_METHOD);
                fieldToPropertyCast = (fType, pType, il) => il.EmitCastToType(fType, pType);
                propertyToFieldCast = (fType, pType, il) => il.EmitCastToType(pType, fType);
                break;

            case CILTypeCode.Int64:
            case CILTypeCode.UInt64:
                fieldType              = INT64_TYPE;
                iExchangeMethod        = INTERLOCKED_EXCHANGE_I64_METHOD;
                iCompareExchangeMethod = INTERLOCKED_COMPARE_EXCHANGE_I64_METHOD;
                break;

            case CILTypeCode.Boolean:
                fieldType              = INT32_TYPE;
                iExchangeMethod        = INTERLOCKED_EXCHANGE_I32_METHOD;
                iCompareExchangeMethod = INTERLOCKED_COMPARE_EXCHANGE_I32_METHOD;
                fieldToPropertyCast    = (fType, pType, il) => il.EmitLoadInt32(0).EmitCeq().EmitLoadInt32(0).EmitCeq();
                propertyToFieldCast    = (fType, pType, il) => { var isTrueLabelWrapper = il.DefineLabel(); var afterConversionLabelWrapper = il.DefineLabel(); il.EmitBranch(BranchType.IF_TRUE, isTrueLabelWrapper); il.EmitLoadInt32(0); il.EmitBranch(BranchType.ALWAYS, afterConversionLabelWrapper); il.MarkLabel(isTrueLabelWrapper); il.EmitLoadInt32(1); il.MarkLabel(afterConversionLabelWrapper); };
                break;

            case CILTypeCode.Byte:
            case CILTypeCode.Char:
            case CILTypeCode.Int16:
            case CILTypeCode.Int32:
            case CILTypeCode.SByte:
            case CILTypeCode.UInt16:
            case CILTypeCode.UInt32:
                fieldType              = INT32_TYPE;
                iExchangeMethod        = INTERLOCKED_EXCHANGE_I32_METHOD;
                iCompareExchangeMethod = INTERLOCKED_COMPARE_EXCHANGE_I32_METHOD;
                break;

            case CILTypeCode.Double:
                iExchangeMethod        = this.isSilverLight ? INTERLOCKED_EXCHANGE_I64_METHOD : INTERLOCKED_EXCHANGE_R64_METHOD;
                iCompareExchangeMethod = this.isSilverLight ? INTERLOCKED_COMPARE_EXCHANGE_I64_METHOD : INTERLOCKED_COMPARE_EXCHANGE_R64_METHOD;
                fieldType = this.isSilverLight ? INT64_TYPE : DOUBLE_TYPE;
                if (this.isSilverLight)
                {
                    fieldToPropertyCast = (fType, pType, il) => il.EmitCall(INT64_BITS_TO_DOUBLE);
                    propertyToFieldCast = (fType, pType, il) => il.EmitCall(DOUBLE_BITS_TO_INT64);
                }
                break;

            case CILTypeCode.Single:
                iExchangeMethod        = this.isSilverLight ? INTERLOCKED_EXCHANGE_I32_METHOD : INTERLOCKED_EXCHANGE_R32_METHOD;
                iCompareExchangeMethod = this.isSilverLight ? INTERLOCKED_COMPARE_EXCHANGE_I32_METHOD : INTERLOCKED_COMPARE_EXCHANGE_R32_METHOD;
                fieldType = this.isSilverLight ? INT32_TYPE : SINGLE_TYPE;
                if (this.isSilverLight)
                {
                    // TODO this is slow
                    // Field to property -> BitConverter.ToInt32(BitConverter.GetBytes(<field>), 0);
                    // Property to field -> BitConverter.ToSingle(BitConverter.GetBytes(<property>), 0);
                    fieldToPropertyCast = (fType, pType, il) => il.EmitCall(GET_BYTES_INT32).EmitLoadInt32(0).EmitCall(BYTES_TO_SINGLE);
                    propertyToFieldCast = (fType, pType, il) => il.EmitCall(GET_BYTES_SINGLE).EmitLoadInt32(0).EmitCall(BYTES_TO_INT32);
                }
                break;

            default:
                throw new ArgumentException("Invalid type code: " + tc);
            }
            if (fieldToPropertyCast == null)
            {
                fieldToPropertyCast = (fType, pType, il) => il.EmitNumericConversion(fType, pType, false);
            }
            if (propertyToFieldCast == null)
            {
                propertyToFieldCast = (fType, pType, il) => il.EmitNumericConversion(pType, fType, false);
            }


            var fieldTypeActual = fieldType;

            read = new Action <CILField, MethodIL>((field, il) =>
            {
                // just load this field
                il.EmitLoadThisField(field);
                fieldToPropertyCast(fieldTypeActual, propertyType, il);
            });
            read32 = !this.isSilverLight && CILTypeCode.Int64 == fieldType.GetTypeCode(CILTypeCode.Empty) ? new Action <CILField, MethodIL>((field, il) =>
            {
                // Interlocked.Read(ref this.<field>);
                il
                .EmitLoadThisFieldAddress(field)
                .EmitCall(INTERLOCKED_READ_I64_METHOD);
                fieldToPropertyCast(fieldTypeActual, propertyType, il);
            }) : null;
            write = (field, il) =>
            {
                // Interlocked.Exchange(ref this.<field>, (<field type>)value);
                il
                .EmitLoadThisFieldAddress(field)
                .EmitLoadArg(1);
                propertyToFieldCast(fieldTypeActual, propertyType, il);
                il.EmitCall(iExchangeMethod);
            };
            compareExchange = (field, il) =>
            {
                // Interlocked.CompareExchange(ref this._property, <arg-2>, <arg-1>);
                il
                .EmitLoadThisFieldAddress(field)
                .EmitLoadArg(2);
                propertyToFieldCast(fieldTypeActual, propertyType, il);
                il.EmitLoadArg(1);
                propertyToFieldCast(fieldTypeActual, propertyType, il);
                il.EmitCall(iCompareExchangeMethod);
                fieldToPropertyCast(fieldTypeActual, propertyType, il);
            };
        }
 /// <summary>
 /// Creates a new <see cref="CILMethodSignature"/> which has all its information specified from the parameters of this method.
 /// </summary>
 /// <param name="ctx">The current <see cref="CILReflectionContext"/>.</param>
 /// <param name="currentModule">The current <see cref="CILModule"/>.</param>
 /// <param name="callingConventions">The <see cref="UnmanagedCallingConventions"/> for the method signature.</param>
 /// <param name="returnType">The return type for the method signature.</param>
 /// <param name="paramTypes">The types of the parameters.</param>
 /// <returns>A new <see cref="CILMethodSignature"/>.</returns>
 /// <exception cref="NullReferenceException">If <paramref name="ctx"/> is <c>null</c>.</exception>
 /// <exception cref="ArgumentNullException">If <paramref name="currentModule"/>, <paramref name="returnType"/> or any of the types within <paramref name="paramTypes"/> is <c>null</c>.</exception>
 /// <seealso cref="CILMethodSignature"/>
 public static CILMethodSignature NewMethodSignature(this CILReflectionContext ctx, CILModule currentModule, UnmanagedCallingConventions callingConventions, CILTypeBase returnType, params CILTypeBase[] paramTypes)
 {
     return(NewMethodSignature(ctx, currentModule, callingConventions, returnType, null, paramTypes.Select(pt => Tuple.Create((CILCustomModifier[])null, pt)).ToArray()));
 }
Beispiel #24
0
        //protected virtual void EmitEventCheckMethodForWeaklyReferencedEvents(
        //   CILField eventField,
        //   MethodIL il
        //   )
        //{
        //   il.EmitLoadThisField( eventField )
        //     .EmitCall( WEAK_EVENT_ARRAY_CLEANUP_METHOD )
        //     .EmitLoadNull()
        //     .EmitCeq()
        //     .EmitLoadInt32( 0 )
        //     .EmitCeq()
        //     .EmitReturn();
        //}

        protected virtual void EmitEventInvocationMethodForStronglyReferencedEvents(
            EventModel eventModel,
            CompositeTypeGenerationInfo thisGenerationInfo,
            CILField eventField,
            CILTypeBase eventType,
            CompositeMethodGenerationInfo invokeMethod,
            CILMethod eventMethodToInvoke
            )
        {
            this.EmitEventInvocationMethodCore(
                eventModel,
                thisGenerationInfo,
                eventField,
                eventType,
                invokeMethod,
                eventMethodToInvoke,
                (eventLB, invocationStyle, exceptionType) =>
            {
                if (EventInvocation.INVOKE_DIRECTLY.Equals(invocationStyle))
                {
                    // Invocation method:
                    // private <return-type> Event<idx>Invoke(<args>)
                    // {
                    //    <event-type> evt = this._event<idx>;
                    //    if (evt != null)
                    //    {
                    //       (return) this._event<idx>(<args>);
                    //    } else <if has return type other than void>
                    //    {
                    //       throw new InvalidOperationException("The event " + <event name> + " is not set.");
                    //    }
                    // }
                    this.EmitEventInvocationWithTryCatchIfNeeded(
                        invocationStyle,
                        exceptionType,
                        invokeMethod,
                        eventMethodToInvoke,
                        il => il.EmitLoadLocal(eventLB),
                        false
                        );
                }
                else
                {
                    var il = invokeMethod.IL;
                    //  foreach ( Delegate handler in evt.GetInvocationList() )
                    //  {
                    //    try
                    //    {
                    //       result = handler(<args>);
                    //    }
                    //    catch ( Exception exc )
                    //    {
                    //      if ( exceptions == null )
                    //      {
                    //         exceptions = new LinkedList<Exception>();
                    //      }
                    //      exceptions.AddLast( exc );
                    //    }
                    //  }
                    var handlersB = invokeMethod.GetOrCreateLocal(LB_EVENT_HANDLERS);
                    il
                    .EmitLoadLocal(eventLB)
                    .EmitCall(GET_INVOCATION_LIST_METHOD)
                    .EmitStoreLocal(handlersB)

                    .EmitSimpleForLoop(
                        il2 =>
                    {
                        // Int32 index = 0;
                        var idxB = invokeMethod.GetOrCreateLocal(LB_INDEX);
                        il2
                        .EmitLoadInt32(0)
                        .EmitStoreLocal(idxB);
                        return(idxB);
                    },
                        (il2, idxB, loopBodyStartLabel) =>
                    {
                        // index < list.Length
                        il2
                        .EmitLoadLocal(idxB)
                        .EmitLoadLocal(handlersB)
                        .EmitLoadArrayLength()
                        .EmitNumericConversion(CILTypeCode.UInt32, CILTypeCode.Int32, false)
                        .EmitBranch(BranchType.IF_FIRST_LESSER_THAN_SECOND, loopBodyStartLabel);
                    },
                        E_MethodIL.EmitLeftPlusPlus,
                        (il2, idxB) =>
                    {
                        this.EmitEventInvocationWithTryCatchIfNeeded(
                            invocationStyle,
                            exceptionType,
                            invokeMethod,
                            eventMethodToInvoke,
                            il3 =>
                        {
                            il3
                            .EmitLoadLocal(handlersB)
                            .EmitLoadLocal(idxB)
                            .EmitLoadElement(handlersB.LocalType)
                            .EmitCastToType(handlersB.LocalType.GetElementType(), eventType);
                        },
                            true
                            );
                    }
                        );
                }
            });
        }
    /// <summary>
    /// Creates a new <see cref="CILMethodSignature"/> which has all its information specified from the parameters of this method.
    /// </summary>
    /// <param name="ctx">The current <see cref="CILReflectionContext"/>.</param>
    /// <param name="currentModule">The current <see cref="CILModule"/>.</param>
    /// <param name="callingConventions">The <see cref="UnmanagedCallingConventions"/> for the method signature.</param>
    /// <param name="returnType">The return type for the method signature.</param>
    /// <param name="returnParamMods">The <see cref="CILCustomModifier"/>s for the method signature. May be <c>null</c> if no modifiers should be used.</param>
    /// <param name="parameters">The parameter information for the method signature. Each element is a tuple containing <see cref="CILCustomModifier"/>s and type for the parameter. Custom modifiers array may be <c>null</c> if no modifiers should be used.</param>
    /// <returns>A new <see cref="CILMethodSignature"/>.</returns>
    /// <exception cref="NullReferenceException">If <paramref name="ctx"/> is <c>null</c>.</exception>
    /// <exception cref="ArgumentNullException">If <paramref name="currentModule"/>, <paramref name="returnType"/> or any of the types within <paramref name="parameters"/> is <c>null</c>.</exception>
    /// <seealso cref="CILMethodSignature"/>
    public static CILMethodSignature NewMethodSignature(this CILReflectionContext ctx, CILModule currentModule, UnmanagedCallingConventions callingConventions, CILTypeBase returnType, CILCustomModifier[] returnParamMods, params Tuple <CILCustomModifier[], CILTypeBase>[] parameters)
    {
        if (ctx == null)
        {
            // Throw nullref explicitly for consistency (since it is 'this' parameter)
            // Because CILMethodSignatureImpl ctor throws ArgumentNullException
            throw new NullReferenceException();
        }
        var cctx = (CILReflectionContextImpl)ctx;

        return(new CILMethodSignatureImpl(ctx, currentModule, callingConventions, returnParamMods == null ? null : cctx.CollectionsFactory.NewListProxyFromParams(returnParamMods), returnType, parameters.Select(t => Tuple.Create(t.Item1 == null ? null : cctx.CollectionsFactory.NewListProxyFromParams(t.Item1), t.Item2)).ToList(), null));
    }