protected virtual void EmitThrowIfExceptionListHasAny(CompositeMethodGenerationInfo methodGenInfo, CILConstructor exceptionCtor) { var exceptionListB = methodGenInfo.GetLocalOrThrow(LB_EXCEPTION_LIST); var il = methodGenInfo.IL; var noThrowLabel = il.DefineLabel(); il .EmitLoadLocal(exceptionListB) .EmitBranch(BranchType.IF_FALSE, noThrowLabel) .EmitLoadLocal(exceptionListB) .EmitThrowNewException(exceptionCtor) .MarkLabel(noThrowLabel); }
protected virtual void EmitPropertyCompareExchangeMethod( PropertyModel propertyModel, CompositeTypeGenerationInfo thisGenerationInfo, CILField propertyField, CompositeMethodGenerationInfo methodGenInfo, Action <CILField, MethodIL> compareExchangeAction ) { var il = methodGenInfo.IL; this.EmitThrowIfApplicationNotActiveWithoutLocalVariable(thisGenerationInfo, il); this.EmitCheckPropertyImmutability(propertyModel, thisGenerationInfo, il); // return Interlocked.CompareExchange(ref this._property, <arg-2>, <arg-1>); compareExchangeAction(propertyField, il); il.EmitReturn(); }
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(); }
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(); }
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 EmitStoreExceptionListWithinCatch( CompositeMethodGenerationInfo methodGenInfo ) { var il = methodGenInfo.IL; var exceptionB = methodGenInfo.GetOrCreateLocal(LB_EXCEPTION); il.EmitStoreLocal(exceptionB); var exceptionListB = methodGenInfo.GetOrCreateLocal(LB_EXCEPTION_LIST); var exceptionsOKLabel = il.DefineLabel(); il .EmitLoadLocal(exceptionListB) .EmitBranch(BranchType.IF_TRUE, exceptionsOKLabel) .EmitNewObject(EXCEPTION_LIST_CTOR) .EmitStoreLocal(exceptionListB) .MarkLabel(exceptionsOKLabel) .EmitLoadLocal(exceptionListB) .EmitLoadLocal(exceptionB) .EmitCall(ADD_LAST_METHOD.ChangeDeclaringType(((CILType)exceptionListB.LocalType).GenericArguments.ToArray())); }
protected virtual void EmitEventInvocationWithTryCatchIfNeeded( EventInvocation invocationStyle, Type exceptionType, CompositeMethodGenerationInfo invokeMethod, CILMethod eventMethodToInvoke, Action <MethodIL> loadEventAction, Boolean storeResult ) { invokeMethod.IL.EmitTryCatch( EXCEPTION_TYPE, il2 => { loadEventAction(il2); for (Int32 idx = 0; idx < invokeMethod.Parameters.Count; ++idx) { il2.EmitLoadArg(invokeMethod.Parameters[idx].Position + 1); } il2.EmitCall(eventMethodToInvoke); if (storeResult && !VOID_TYPE.Equals(eventMethodToInvoke.GetReturnType())) { var resultB = invokeMethod.GetOrCreateLocal(LB_RESULT, invokeMethod.ReturnType); il2.EmitStoreLocal(resultB); } }, EventInvocation.INVOKE_DIRECTLY.Equals(invocationStyle) ? (Action <MethodIL>)null : il2 => { if (exceptionType != null) { this.EmitStoreExceptionListWithinCatch(invokeMethod); } else { throw new InternalException("Non-direct event invocation style, but no exception type specified."); } }, false ); }
public void RegisterCompositeMethodGenerationInfo(CompositeMethodModel model, CompositeMethodGenerationInfo info) { this._compositeMethodGenerationInfos.TryAdd(model, info); }
protected virtual void EmitPropertyRelatedThings( CompositeCodeGenerationInfo codeGenerationInfo, CompositeTypeGenerationInfo publicCompositeGenInfo, CompositeTypeGenerationInfo thisGenerationInfo, CompositeMethodGenerationInfo thisMethodGenerationInfo, PropertyModel propertyModel, Type genericPropertyMixinType ) { var nPropertyInfo = propertyModel.NativeInfo; var propertyInfo = nPropertyInfo.NewWrapper(this.ctx); if (this.IsCompositeGeneratedProperty(thisGenerationInfo, propertyModel, genericPropertyMixinType)) { var propertyIdx = thisGenerationInfo.AutoGeneratedPropertyInfos.Count; var propertyType = TypeGenerationUtils.CreateTypeForEmitting(propertyInfo.GetPropertyType(), thisGenerationInfo.GenericArguments, null); CILTypeBase fieldType; Action <CILField, MethodIL> readMethod; Action <CILField, MethodIL> read32Method; Action <CILField, MethodIL> writeMethod; Action <CILField, MethodIL> compareExchangeMethodEmitter; this.GetReadAndWriteMethods(propertyType, out readMethod, out read32Method, out writeMethod, out compareExchangeMethodEmitter, out fieldType); // Field: // private <property type or Object> _property<idx>; var propertyField = thisGenerationInfo.Builder.AddField( PROPERTY_FIELD_PREFIX + propertyIdx, fieldType, FieldAttributes.Private ); // Field getter var getter = thisGenerationInfo.Builder.AddMethod( PROPERTY_METHOD_PREFIX + propertyIdx + PROPERTY_GETTER_POSTFIX, MethodAttributes.Private | MethodAttributes.HideBySig, CallingConventions.HasThis); this.EmitPropertyGetterMethod(codeGenerationInfo, propertyModel, publicCompositeGenInfo, thisGenerationInfo, propertyField, propertyType, (CompositeMethodGenerationInfo) new CompositeMethodGenerationInfoImpl(getter, null, null).WithReturnType(propertyType) /*.WithParameters( propertyInfo.GetIndexParameters().Select( p => Tuple.Create( p.ParameterType, p.Attributes ) ) )*/, readMethod); // Field getter for 32-bit processes, if required CILMethod getter32 = null; if (read32Method != null) { getter32 = thisGenerationInfo.Builder.AddMethod( PROPERTY_METHOD_PREFIX + propertyIdx + PROPERTY_GETTER32_POSTFIX, MethodAttributes.Private | MethodAttributes.HideBySig, CallingConventions.HasThis); this.EmitPropertyGetterMethod(codeGenerationInfo, propertyModel, publicCompositeGenInfo, thisGenerationInfo, propertyField, propertyType, (CompositeMethodGenerationInfo) new CompositeMethodGenerationInfoImpl(getter32, null, null).WithReturnType(propertyType) /*.WithParameters( propertyInfo.GetIndexParameters().Select( p => Tuple.Create( p.ParameterType, p.Attributes ) ) )*/, read32Method); } // Field setter var setter = thisGenerationInfo.Builder.AddMethod( PROPERTY_METHOD_PREFIX + propertyIdx + PROPERTY_SETTER_POSTFIX, MethodAttributes.Public | MethodAttributes.HideBySig, // TODO MethodAttributes.Assembly when [InternalsVisibleTo(...)] attribute will be applied to all generated assemblies. CallingConventions.HasThis); this.EmitPropertySetterMethod(codeGenerationInfo, propertyModel, publicCompositeGenInfo, thisGenerationInfo, propertyField, fieldType, propertyType, (CompositeMethodGenerationInfo) new CompositeMethodGenerationInfoImpl(setter, null, null).WithParameters(Enumerable.Repeat(Tuple.Create(propertyType, ParameterAttributes.None), 1)), writeMethod); // Exchange method var exchangeMethod = thisGenerationInfo.Builder.AddMethod( PROPERTY_METHOD_PREFIX + propertyIdx + PROPERTY_EXCHANGE_POSTFIX, MethodAttributes.Private | MethodAttributes.HideBySig, CallingConventions.HasThis); this.EmitPropertyExchangeMethod(propertyModel, thisGenerationInfo, propertyField, fieldType, propertyType, setter, (CompositeMethodGenerationInfo) new CompositeMethodGenerationInfoImpl(exchangeMethod, null, null).WithReturnType(propertyType).WithParameters(Enumerable.Repeat(Tuple.Create(propertyType, ParameterAttributes.None), 1)), writeMethod); // CompareExchange method var compareExchangeMethod = thisGenerationInfo.Builder.AddMethod( PROPERTY_METHOD_PREFIX + propertyIdx + PROPERTY_COMPARE_EXCHANGE_POSTFIX, MethodAttributes.Private | MethodAttributes.HideBySig, CallingConventions.HasThis); this.EmitPropertyCompareExchangeMethod(propertyModel, thisGenerationInfo, propertyField, (CompositeMethodGenerationInfo) new CompositeMethodGenerationInfoImpl(compareExchangeMethod, null, null).WithReturnType(propertyType).WithParameters(Enumerable.Repeat(Tuple.Create(propertyType, ParameterAttributes.None), 2)), compareExchangeMethodEmitter); thisGenerationInfo.AutoGeneratedPropertyInfos.Add(nPropertyInfo, new PropertyGenerationInfo( this.EmitRefMethodForPropertyOrEvent(propertyField, PROPERTY_METHOD_PREFIX + propertyIdx + REF_INVOKER_METHOD_SUFFIX), propertyModel, propertyField, getter, getter32, setter, exchangeMethod, compareExchangeMethod, propertyType )); } if (this.NeedToEmitAdditionalMemberInfo(thisGenerationInfo, propertyInfo.Name, (parent, name) => parent.DeclaredProperties.FirstOrDefault(p => Object.Equals(p.Name, name)))) { // Need to define property if we inherit property directly from interface var name = propertyInfo.Name; if (thisGenerationInfo.RawPropertyInfos.Keys.Any(pInfo => pInfo.Name.Equals(name))) { // We already have property with the same name from different type name = QualifiedName.FromMemberInfo(nPropertyInfo).ToString(); } CILProperty pBuilder; if (!thisGenerationInfo.RawPropertyInfos.TryGetValue(nPropertyInfo, out pBuilder)) { pBuilder = thisGenerationInfo.Builder.AddProperty( name, propertyInfo.Attributes ); thisGenerationInfo.RawPropertyInfos.Add(nPropertyInfo, pBuilder); } if (thisMethodGenerationInfo.MethodFromModel.Equals(propertyInfo.GetMethod)) { pBuilder.GetMethod = thisMethodGenerationInfo.Builder; } else if (thisMethodGenerationInfo.MethodFromModel.Equals(propertyInfo.SetMethod)) { pBuilder.SetMethod = thisMethodGenerationInfo.Builder; } else { throw new InternalException("Found a property, but neither setter nor getter matched the method being emitted. Property is " + propertyInfo + ", method is " + thisMethodGenerationInfo.MethodFromModel + "."); } } }
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(); }
protected virtual void EmitEventRelatedThings( CompositeTypeGenerationInfo thisGenerationInfo, CompositeMethodGenerationInfo thisMethodGenerationInfo, EventModel eventModel, Type genericEventMixinType ) { var nEventInfo = eventModel.NativeInfo; var eventInfo = nEventInfo.NewWrapper(this.ctx); CompositeMethodGenerationInfo invokeMethod = null; if (this.IsCompositeGeneratedEvent(thisGenerationInfo, eventModel, genericEventMixinType)) { var eventIdx = thisGenerationInfo.AutoGeneratedEventInfos.Count; var eventType = TypeGenerationUtils.CreateTypeForEmitting(eventInfo.EventHandlerType, thisGenerationInfo.GenericArguments, null); var invokeMethodFromModel = eventModel.NativeInfo.EventHandlerType.GetMethod(DELEGATE_INVOKE_METHOD_NAME).NewWrapper(this.ctx); CILTypeBase fieldType; Action <CILField, MethodIL> addAction, removeAction; Action <EventModel, CompositeTypeGenerationInfo, CILField, CILTypeBase, CompositeMethodGenerationInfo, CILMethod> invokeAction; Action <CILField, MethodIL> checkAction; this.CreateEmittingActionsForEvent( eventModel, eventType, out fieldType, out addAction, out removeAction, out invokeAction, out checkAction ); // Field: // private <field type> _event<idx>; var eventField = thisGenerationInfo.Builder.AddField( EVENT_FIELD_PREFIX + eventIdx, fieldType, FieldAttributes.Private ); var addMethod = this.ImplementMethodForEmitting( thisGenerationInfo, eventModel.AddMethod.NativeInfo.NewWrapper(this.ctx), EVENT_METHOD_PREFIX + eventIdx + EVENT_ADDITION_POSTFIX, MethodAttributes.Private | MethodAttributes.HideBySig, false ); this.EmitThrowIfApplicationNotActiveWithoutLocalVariable(thisGenerationInfo, addMethod.IL); addAction(eventField, addMethod.IL); CompositeMethodGenerationInfo removeMethod = this.ImplementMethodForEmitting( thisGenerationInfo, eventModel.RemoveMethod.NativeInfo.NewWrapper(this.ctx), EVENT_METHOD_PREFIX + eventIdx + EVENT_REMOVAL_POSTFIX, MethodAttributes.Private | MethodAttributes.HideBySig, false ); this.EmitThrowIfApplicationNotActiveWithoutLocalVariable(thisGenerationInfo, removeMethod.IL); removeAction(eventField, removeMethod.IL); invokeMethod = this.ImplementMethodForEmitting( thisGenerationInfo, decType => TypeGenerationUtils.CreateTypeForEmittingCILType(decType, thisGenerationInfo.GenericArguments, null), invokeMethodFromModel, EVENT_METHOD_PREFIX + eventIdx + EVENT_INVOCATION_POSTFIX, MethodAttributes.Private | MethodAttributes.HideBySig, false); var eventMethodToInvoke = invokeMethod.OverriddenMethod; this.EmitThrowIfApplicationNotActiveWithoutLocalVariable(thisGenerationInfo, invokeMethod.IL); invokeAction(eventModel, thisGenerationInfo, eventField, eventType, invokeMethod, eventMethodToInvoke); // Field clearer method: // private void Event<idx>Clear() // { // Interlocked.Exchange<TEvent>(ref this._event<idx>, null); // } var eventClearMB = thisGenerationInfo.Builder.AddMethod( EVENT_METHOD_PREFIX + eventIdx + EVENT_CLEAR_POSTFIX, MethodAttributes.Private | MethodAttributes.HideBySig, CallingConventions.HasThis); var il = eventClearMB.MethodIL; this.EmitThrowIfApplicationNotActiveWithoutLocalVariable(thisGenerationInfo, il); il.EmitLoadThisFieldAddress(eventField); il.EmitLoadNull(); il.EmitCall(INTERLOCKED_EXCHANGE_METHOD_GDEF.MakeGenericMethod(fieldType)); il.EmitPop(); il.EmitReturn(); // Field checker method: // private Boolean Event<idx>Checker() // { // // for strong refs // return this._event<idx>; // // for weak refs // return // } var eventCheckerMB = thisGenerationInfo.Builder.AddMethod( EVENT_METHOD_PREFIX + eventIdx + EVENT_CHECKER_POSTFIX, MethodAttributes.Private | MethodAttributes.HideBySig, CallingConventions.HasThis ); eventCheckerMB.ReturnParameter.ParameterType = BOOLEAN_TYPE; il = eventCheckerMB.MethodIL; this.EmitThrowIfApplicationNotActiveWithoutLocalVariable(thisGenerationInfo, il); checkAction(eventField, il); thisGenerationInfo.AutoGeneratedEventInfos.Add( nEventInfo, new EventGenerationInfo( this.EmitRefMethodForPropertyOrEvent(eventField, EVENT_METHOD_PREFIX + eventIdx + REF_INVOKER_METHOD_SUFFIX), eventModel, eventType, eventField, addMethod.Builder, removeMethod.Builder, invokeMethod.Builder, eventClearMB, eventCheckerMB ) ); } if (this.NeedToEmitAdditionalMemberInfo(thisGenerationInfo, eventInfo.Name, (parent, name) => parent.DeclaredEvents.FirstOrDefault(evt => Object.Equals(evt.Name, name)))) { // Need to define event if we inherit property directly from interface var name = eventInfo.Name; if (thisGenerationInfo.RawPropertyInfos.Keys.Any(pInfo => pInfo.Name.Equals(name))) { // We already have event with the same name from different type name = QualifiedName.FromMemberInfo(nEventInfo).ToString(); } CILEvent eBuilder; if (!thisGenerationInfo.RawEventInfos.TryGetValue(nEventInfo, out eBuilder)) { eBuilder = thisGenerationInfo.Builder.AddEvent( name, eventInfo.Attributes, TypeGenerationUtils.CreateTypeForEmitting(eventInfo.EventHandlerType, thisGenerationInfo.GenericArguments, null) ); if (invokeMethod != null) { eBuilder.RaiseMethod = invokeMethod.Builder; } thisGenerationInfo.RawEventInfos.Add(nEventInfo, eBuilder); } if (thisMethodGenerationInfo.MethodFromModel.Equals(eventInfo.AddMethod)) { eBuilder.AddMethod = thisMethodGenerationInfo.Builder; } else if (thisMethodGenerationInfo.MethodFromModel.Equals(eventInfo.RemoveMethod)) { eBuilder.RemoveMethod = thisMethodGenerationInfo.Builder; } else { throw new InternalException("Found an event, but neither adder nor remover methods matched the method being emitted. Event is " + eventInfo + ", method is " + thisMethodGenerationInfo.MethodFromModel + "."); } } }
//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 ); } ); } }); }
protected override void EmitAfterCompositeMethodBodyBegan( IEnumerable <FragmentTypeGenerationInfo> fragmentTypeGenerationInfos, CompositeTypeGenerationInfo thisGenerationInfo, CompositeMethodGenerationInfo thisMethodGenerationInfo, SPI.Model.CompositeMethodModel compositeMethodModel ) { var instanceableModel = compositeMethodModel.CompositeModel; // Need to emit code related to activation var il = thisMethodGenerationInfo.IL; var cInstanceB = thisMethodGenerationInfo.GetLocalOrThrow(LB_C_INSTANCE); LocalBuilder compositeMethodModelB = null; Boolean hasOnInvocationInjections = this.HasOnInvocationInjections(compositeMethodModel.CompositeModel.SpecialMethods.Where(sMethod => sMethod.AllAttributes.OfType <ActivateAttribute>().Any() || sMethod.AllAttributes.OfType <PrototypeAttribute>().Any())); if (hasOnInvocationInjections) { this.InitializeComplexMethodModelLocalIfNecessary(compositeMethodModel, thisMethodGenerationInfo, out compositeMethodModelB); } // cInstance.ActivateIfNeeded(<method-index>, <gargs-info>, <next fragment>); il.EmitLoadLocal(cInstanceB) .EmitLoadInt32(compositeMethodModel.MethodIndex); if (thisMethodGenerationInfo.Builder.GenericArguments.Count > 0) { // new MethodGenericArgumentsInfo(<method-handle>, <type-handle>) var cMethodInfo = thisMethodGenerationInfo.OverriddenMethod.MakeGenericMethod(thisMethodGenerationInfo.GenericArguments.ToArray()); il.Add(new OpCodeInfoWithMethodToken( OpCodes.Ldtoken, cMethodInfo)) .Add(new OpCodeInfoWithTypeToken( OpCodes.Ldtoken, cMethodInfo.DeclaringType )); il.EmitNewObject(this.METHOD_GENERIC_ARGUMENTS_INFO_CTOR); } else { il.EmitLoadNull(); } if (hasOnInvocationInjections) { il.EmitLoadLocal(compositeMethodModelB); if (compositeMethodModel.Concerns.Any()) { il.EmitCall(CONCERN_MODELS_GETTER) .EmitLoadInt32(0) .EmitCall(CONCERN_MODELS_INDEXER); } else { il.EmitCall(MIXIN_MODEL_GETTER); } } else { il.EmitLoadNull(); } il.EmitCall(SERVICE_COMPOSITE_ACTIVATE_IF_NEEDED_METHOD); }