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 ) { }
internal void BeginCatchBlock(CILTypeBase exceptionType) { var info = this._currentExceptionBlocks.Peek(); info._exceptionType = exceptionType; info.HandlerBegun(ExceptionBlockType.Exception, this._opCodes.Count); }
internal static void CheckTypeForMethodSig(CILModule thisModule, ref CILTypeBase type) { if (TypeKind.MethodSignature == type.TypeKind && !Object.Equals(thisModule, type.Module)) { type = ((CILMethodSignature)type).CopyToOtherModule(thisModule); } }
internal LocalBuilderImpl(Int32 idx, CILTypeBase type, Boolean pinned) { ArgumentValidator.ValidateNotNull("Local type", type); this._idx = idx; this._localType = type; this._pinned = pinned; }
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); }
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; //} }
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); }
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)); }
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; } } }
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; }
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(); }
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(); }
/// <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; }
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) { }
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(); }
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 ) { }
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())); }
//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)); }