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();
        }
Exemplo n.º 2
0
        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 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();
        }
Exemplo n.º 4
0
 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
         );
 }
Exemplo n.º 5
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
                            );
                    }
                        );
                }
            });
        }